I need to print those numbers in console:
0
1
2
3
-
5
6
7
8
-
10
11
12
13
-
15
16
17
18
As you can see I am not printing 4, 9, 14
.
So I coded this:
top = 18
counter = 0
print("Using option 1")
for i in range(top -2):
print(counter)
if counter == 3 or counter == 8 or counter == 13:
counter = counter + 2
else:
counter = counter + 1
print("Using option 2")
i = -1
while i < top:
if i == 3 or i == 8 or i == 13:
i = i + 2
print(i)
else:
i = i +1
print(i)
The output of the above code is:
Using option 1
0
1
2
3
5
6
7
8
10
11
12
13
15
16
17
18
Using option 2
0
1
2
3
5
6
7
8
10
11
12
13
15
16
17
18
As you can see my code is working well.
In option1
I used a for
loop.
And in option2
I used a while
loop.
So I would like to know if there is a way to make some of that option more dynamic just by using the top
value, or improve the algorithm.
-
2\$\begingroup\$ Are you printing the hyphens, or not? Your specification says yes, your code says no. \$\endgroup\$Reinderien– Reinderien2022年10月19日 11:54:50 +00:00Commented Oct 19, 2022 at 11:54
3 Answers 3
- Save your non-printed into single set
exceptions = (4, 9, 14)
, that way you can test it nicely asindex in exceptions
orindex not in exceptions
for negative. - Rather than trying to fiddle and increment your counter value yourself, just use range index and print only if you want it to print:
Example:
top = 20
exceptions = set((4, 9, 14,))
for index in range(top):
if index not in exceptions:
print(index)
If you were to go more in functional way (I recommend that), you can use filter
function:
top = 20
exceptions = set((4, 9, 14,))
for index in filter(lambda i: i not in exceptions, range(top)):
print(index)
Edit:
Changed exceptions
from tuple
to set
as suggested in a comment.
-
\$\begingroup\$ Isn't the more functional way to
join()
on an iterable? \$\endgroup\$Reinderien– Reinderien2022年10月19日 11:42:39 +00:00Commented Oct 19, 2022 at 11:42 -
\$\begingroup\$ Now I understand what you meant :) I used
filter
, cause in my head, printing is usually something temporary to test, but then you in reality use the data in some other way. \$\endgroup\$K.H.– K.H.2022年10月19日 12:14:38 +00:00Commented Oct 19, 2022 at 12:14 -
\$\begingroup\$ Since OP is an admitted beginner, could you explain a little how
lambda
works here? \$\endgroup\$BruceWayne– BruceWayne2022年10月19日 18:03:26 +00:00Commented Oct 19, 2022 at 18:03 -
1\$\begingroup\$ The one other problem with both your original solutions and this solution is performance. For a tuple,
index not in exceptions
will be O(n) for n=len(exceptions). To do better, use:exceptions = set((4, 9, 14))
. This actually won't matter much for 3 exceptions, but have 3000 and it will be critical. \$\endgroup\$David G.– David G.2022年10月23日 15:35:34 +00:00Commented Oct 23, 2022 at 15:35
You need to work harder at identifying the repeating patterns in your code. You're really printing uniformly-spaced groups with separators between them. Uniformly-spaced groups are better-represented with range()
calls. The works can be formatted using two levels of join
: the first within the group, and the second stringing the groups together.
In the following suggested code I've deliberately avoided writing a one-liner to make it easier to understand.
Suggested
spacing = 5
group_starts = range(0, 20, spacing)
separator = '-'
everything = f'\n{separator}\n'.join(
'\n'.join(
str(i) for i in range(start, start + spacing - 1)
)
for start in group_starts
)
print(everything)
How you display it is to your own taste but the core functionality is essentially a range with exceptions. Using hardcode to go through while loops and using lambda functions is all good but it seems overly complicated for a simple function. Perhaps use a reference and construct a list with comprehension. ie:
def start(ex_1, ex_2, ex_3):
ref = [ex_1, ex_2, ex_3]
num_list = [x for x in range(1, 19) if x not in ref]
print(num_list)
start(4, 9, 14)
-
1\$\begingroup\$ Downvote: This solution is not extensible: if a new exception was to be added, a new parameter would have to be added to the function, potentially making all other existing calls to it invalid. Also, as mentioned already in another answer, using a
list
/tuple
makes its time complexity O(N). Aset
would provide a time complexity of O(1). Moreover, prefer immutability over mutability (tuple
overlist
), as it is less error prone. Lastly, therange
is not configurable, making it a non-reusable function \$\endgroup\$Miguel Alorda– Miguel Alorda2022年10月30日 08:16:48 +00:00Commented Oct 30, 2022 at 8:16 -
1\$\begingroup\$ Also, core logic should be separated from presentation to allow reusability. That is, the
print
should not be done within the function \$\endgroup\$Miguel Alorda– Miguel Alorda2022年10月30日 08:17:45 +00:00Commented Oct 30, 2022 at 8:17 -
\$\begingroup\$ The OP said he needs to print the numbers in the console. Not that he wants to run a pep8 format defined operation. To put simply, you dont know what you on about - his question is answered and this runs correctly and does exactly what he is asking to happen. \$\endgroup\$Barb– Barb2022年10月31日 13:29:28 +00:00Commented Oct 31, 2022 at 13:29
-
\$\begingroup\$ @MiguelAlorda's comments are entirely correct. I am also one of the top Python reviewers on the site, so I'm confident I know what I'm on about. \$\endgroup\$2022年10月31日 13:33:24 +00:00Commented Oct 31, 2022 at 13:33
-
1\$\begingroup\$ Please do not edit the question. You are unlikely to edit the question in a way which would be inline with our rules. Sure, we can agree to disagree. You've now got two downvotes and some comments why there are downvotes. Your disagreement with editing your answer means these downvotes and comments will be permanently attached to your answer. And everyone agrees the situation is fine. \$\endgroup\$2022年11月01日 12:29:58 +00:00Commented Nov 1, 2022 at 12:29