Need Help Understanding For loops with Variables in Python - python-3.x

I am going through the book Automate the Boring Stuff with Python, and need help understanding what's really happening with the code.
catNames = []
while True:
print('Enter the name of cat ' + str(len(catNames) + 1) + ' (Or enter nothing to stop.):')
name = input()
if name == '':
break
catNames = catNames + [name]
print('The cat names are:')
for name in catNames:
print(' ' + name)
now it makes sense until
for name in catNames:
print(' ' + name)
I am only used to seeing for loops with range(), and this does not make sense to me. A detailed explanation would be highly appreciated thanks

I will explain it to you on a simple example:
# You create some list of elements
list = [1, 2, 3, 9, 4]
# Using for loop you print out all the elements
for i in list:
print(i)
It will print to the console:
1
2
3
9
4
And you can also do it by using range but you have to know the length of the array:
# You create some list of elements
list = [1, 2, 3, 9, 4]
# get the list length
length = len(list)
# Iterating the index
# same as 'for i in range(len(list))'
for i in range(length):
print(list[i])
Console output will look the same as before

Related

Counting: How do I add a zero if a word does not occur in a list?

I would like to find keywords from a list, but return a zero if the word does not exist (in this case: part). In this example, collabor occurs 4 times and part 0 times.
My current output is
[['collabor', 4]]
But what I would like to have is
[['collabor', 4], ['part', 0]]
str1 = ["collabor", "part"]
x10 = []
for y in wordlist:
for string in str1:
if y.find(string) != -1:
x10.append(y)
from collections import Counter
x11 = Counter(x10)
your_list = [list(i) for i in x11.items()]
rowssorted = sorted(your_list, key=lambda x: x[0])
print(rowssorted)
Although you have not clearly written your problem and requirements,I think I understood the task.
I assume that you have a set of words that may or may not occur in a given list and you want to print the count of those words based on the occurrence in the given list.
Code:
constants=["part","collabor"]
wordlist = ["collabor", "collabor"]
d={}
for const in constants:
d[const]=0
for word in wordlist:
if word in d:
d[word]+=1
else:
d[word]=0
from collections import Counter
x11 = Counter(d)
your_list = [list(i) for i in x11.items()]
rowssorted = sorted(your_list, key=lambda x: x[0])
print(rowssorted)
output:
[['collabor', 2], ['part', 0]]
This approach gives the required output.
In python, to get the count of occurrence dictionary is popular.
Hope it helps!

how can I increment the first number in a range?

Learning python and I need to figure out to to increase the first number in a range?
measures = 4
beats_per_measures = 4
beats = 0
for i in range(0, measures):
for beats in range(1 , beats_per_measure + 1):
print(beats)
so I can get the output to print the beats per measure the number of measures. BOOm. but now I need to increase the first beat by one every measure and I know it's easier than I am making it. I have preformed multiple searches online and I am guessing that because I don't know how to read the complex answers or I don't know how to phrase what I am trying to do is why I have not found an answer yet.
Is this what you need?
I thought you needed each set (1,2,3,4) in the same line.
measures = 4
beats_per_measure = 4
for i in range(measures):
for var_beat in range(beats_per_measure):
var_beat = str(1 + var_beat)
fixed_beat = ' '.join([ str(1+f) for f in range(beats_per_measure)[1:]])
print(var_beat + ' ' + fixed_beat)
I am a little bit confused with your "so on" in your comment.
You can do:
for e in range(1,5):
print(', '.join(map(str, ([e]+list(range(2,5))))))
Prints:
1, 2, 3, 4
2, 2, 3, 4
3, 2, 3, 4
4, 2, 3, 4
Or, perhaps:
>>> print('\n'.join([f"{e}, 2, 3 ,4" for e in range(1,5)]))
# same output
Which could be made dynamic by this:
measures = 4
beats_per_measures = 4
rest_of_measure=', '.join(f'{e}' for e in range(2,beats_per_measures+1))
print('\n'.join([f"{e}, {rest_of_measure}" for e in range(1, measures+1)]))
From your comment, you just want to always print an increasing number followed by 2, 3, 4. So just print the first beat manually based on the measure you're currently processing:
for measure in range(1, measures+1): # Adjust bounds so we don't have to add one inside the loop
print(measure) # Prints the changing value
for beats in range(2, beats_per_measure + 1):
print(beats) # Prints the consistent 2, 3, 4 values
If you want each measure on the same line, the minimal change is to just add end='' or end=' ' to each print and add an empty print() to the end of the outer loop.
A cleaner solution would be to just print each measure all at once; you can unpack a range argument with * to make it operate as separate arguments to print, and use sep to provide the characters you want in between, getting something like:
for measure in range(1, measures + 1):
print(measure, *range(2, beats_per_measure + 1), sep=', ')
# prints:
1, 2, 3, 4
2, 2, 3, 4
3, 2, 3, 4
...
and it's trivial to change the separation to just a single space, sep=' ', or no separation at all, sep=''.
measures = 4
beats_per_measure = 4
for measure in range(0 , measures):
for beats in range(1 , beats_per_measure + 1):
#print(beats)
if beats == 1:
beats += measure
elif beats != 1:
beats = beats
print(beats)
this is the answer I was looking for. It was a ^%^%$ conditional that helped me do it!!! Thanks for all the help can't wait to plug in all of your recommendations to see what else I can do!

How to loop through a constantly updating list?

for i in range(0, len(list_stops)):
for j in range(1, len(list_stops[i])):
current = stops_from_stop(list_stops[i][j])
list_stops.extend(current)
for k in range(0, len(current)):
for m in range(0, len(current[k])):
list_stops_x.extend([current[k][m]])
if id_b in list_stops_x:
#rest of code
list_stops is a list of lists. Eg [[1,2,3], [4,5,6]]
list_stops_x is a single list of all the numbers in list_stops. Eg [1,2,3,4,5,6]. Basically used as a condition to enter the rest of the code with a return statement at the end, so the loop does not repeat.
I find that the loop ends after reaching the final index of the first version of list_stops, but I am constantly extending list_stops and want the loop to carry on into the extensions. So for example if I extend [7,8,9] to list_stops in the loop, if id_b is not found I still want it to loop through [7,8,9], but it stops at 6.
Note: This is only a section of the entire function, but I am quite sure the problem lies here. This is also for an introductory programming course, so a simple solution will do :) The full code is below
def find_path(stops, routes, stop_a, stop_b):
id_a = stop_a[0]
id_b = stop_b[0]
unused = unused_stops()
if id_b in list(unused):
return []
total_route = list()
all_stops = stops_from_stop(id_a)
list_stops_x = stops_from_stop_x(id_a)
list_stops = stops_from_stop(id_a)
for index in range(0, len(all_stops)):
if id_b in all_stops[index]:
return find_route(stops, routes, stop_a, stop_b)
for i in range(0, len(list_stops)):
for j in range(1, len(list_stops[i])):
current = stops_from_stop(list_stops[i][j])
list_stops.extend(current)
for k in range(0, len(current)):
for m in range(0, len(current[k])):
list_stops_x.extend([current[k][m]])
if id_b in list_stops_x:
stops_used_rev = [id_b]
last_route = list_stops[len(list_stops) - 1]
current_stop = last_route[0]
stops_used_rev += [current_stop]
for i in range(0, len(list_stops)):
if (current_stop in list_stops[i]) and (list_stops[i][0] == id_a):
stops_used_rev += [id_a]
break
elif current_stop in list_stops[i]:
current_stop = last_route[0]
stops_used_rev += [current_stop]
stops_used = stops_used_rev[::-1]
for index in range(0, len(stops_used) - 1):
total_route.extend(find_route(stops, routes, stops[stops_used[index]], stops[stops_used[index + 1]]))
return total_route
stops_from_stop finds the list stops accessible from the current stop and appends to another list. stops_from_stops_x does the same but extends instead
So the issue is that we use the range(0, len(list_stops)) if we instead use enumerate in the following way, BEWARE INFINITE LOOP, due too we keep adding elements to the list. So be careful, but this should give the desired result. I have changed some part of the code so I could run it.
Enumerate makes it possible to both get the item of the list (val) and the index that we are currently at.
list_stops = [[1,2,3], [4,5,6]]
list_stops_x = [1,2,3,4,5,6]
newer = [[7, 8, 9], [10, 11, 12]]
id_b = 9
for i, val in enumerate(list_stops):
print(val)
for j in range(1, len(list_stops[i])):
current = newer
list_stops.extend(current)
for k in range(0, len(current)):
for m in range(0, len(current[k])):
list_stops_x.extend([current[k][m]])
# if id_b in list_stops_x:
# print("id_b in")
# break
EDIT 1
in your code that was in the edit suggestion you have loops that look like the following:
for i in range(0, len(list_stops)):
...
These should be replace with the following to fix the issue
for i, val in enumerate(list_stops):
...
I have a difficult time of testing the code, but try replace the for loops with the type that i provided and let me know
Edit 2
If we keep adding to the list ofcourse it will loop infinitely unless we exit somewhere. You can see this example that I add elements to list a from list b and then remove the item. As you see from the output we loop eight times so we know it works, you should reflect such changes in your code
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
for idx, val in enumerate(a):
print("Loop Count: " + str(idx))
if b:
a.append(b[0])
b.remove(b[0])
Loop Count: 0
Loop Count: 1
Loop Count: 2
Loop Count: 3
Loop Count: 4
Loop Count: 5
Loop Count: 6
Loop Count: 7

How to take input from different lines in a list of Python3?

I want list from the user input from different lines WITHOUT knowing the number of lines.
I tried something and don't know how to replace value of 'n' from below code to get input from different WITHOUT requesting number of line from user.
arr = [ int(input()) for i in range(n)]
use a while True loop and keep checking for a special character or string to break the loop.
myList = list()
while True:
inp = input('input > ')
if inp == '-1': # using -1 to break loop, you could put your choice
break
myList.append(inp)
Here is a solution that I found..
it take input as:
1
2
3
4
8
7
5
6
and output as:
[1, 2, 3, 4, 8, 7, 5, 6]
My code is here....
arr = []
while True:
try:
line = input()
except EOFError:
break
arr.append(line)
arr = list(map(int, arr))
print(arr)

Ugly 2 dimensional list. Why?

I'm trying to figure out why my list looks ugly when printed:
alfa = []
alfa.append([])
alfa.append([])
a = 0
a = float(a)
print("Input the points, one per line as x,y.\nStop by entering an empty line.")
while a == 0:
start = input()
if start == '':
a = a + 1
else:
alfa[0].append(start.split(",")[0:1])
alfa[1].append(start.split(",")[1:2])
print(alfa)
with input of:
2,3
12,56
1,2
a
I get this:
[[['2'], ['12'], ['1']], [['3'], ['56'], ['2']]]
While if i try this simple Program found online:
elements = []
elements.append([])
elements.append([])
elements[0].append(1)
elements[0].append(2)
elements[1].append(3)
elements[1].append(4)
print(elements[0][0])
print(elements)
I get this:
[[1, 2], [3, 4]]
Why is this result much tidier than mine?
Try:
alfa[0].append(int(start.split(",")[0]))
alfa[1].append(int(start.split(",")[1]))
>>>[[2, 12, 1], [3, 56, 2]]
You're getting the quote marks because input() is interpreting the input as a string. It doesn't know that you want what you've typed to be a number, so it has to handle it in a default way. You have to tell the code that the input should be interpreted as an int.
Secondly, you're slicing the arrays when you use [0:1] to get an array consisting of the entries from 0 to 0, which is the same as getting element 0 directly, except you get an array with one element rather than just the element you want. Essentially, you are inserting [2] rather than 2.
The data from your input is strings, as shown by the quotation marks. Cast your strings to integers after the input. If you want to have the [1, 2] formatting without the extra brackets then you need to place numbers in alfa[0] and alfa[1] etc..
alfa = []
alfa.append([])
alfa.append([])
a = 0
a = float(a)
print("Input the points, one per line as x,y.\nStop by entering an empty line.")
while a == 0:
start = input()
if start == '':
a = a + 1
else:
alfa[0].append(int(start.split(",")[0]))
alfa[1].append(int(start.split(",")[1]))
print(alfa)
Oh, I see #Andrew McDowell has beat me to this. Well here you go anyway...

Resources