I am working with Google Python class exercises where I am getting this issue -
def front_x(words):
# +++your code here+++
list = []
for i,s in enumerate(words):
print i,s
if s[0] == 'x':
list.append(words.pop(i))
return list
print front_x(['bbb','ccc','axx','xzz','xaa'])
my loop is only iterating from 0 to 3, so print i,s is giving me values till 'xzz'.Please point where I am wrong.
Don't modify something as you're iterating over it. words.pop(i) modifies words, which you're iterating over via enumerate().
I'd suggest looking at list comprehensions for accomplishing your apparent goal.
Yes, you probably shouldn't words.pop(). The word you want is most likely in s - add that to the list instead.
Also, note that naming a list "list", will more or less erase the "list" builtin type from your local scope. It's not a make or break kind of deal, but it's something pylint would warn about.
Related
This question already has answers here:
Strange result when removing item from a list while iterating over it
(8 answers)
Closed 7 years ago.
l = range(100)
for i in l:
print i,
print l.pop(0),
print l.pop(0)
The above python code gives the output quite different from expected. I want to loop over items so that I can skip an item while looping.
Please explain.
Never alter the container you're looping on, because iterators on that container are not going to be informed of your alterations and, as you've noticed, that's quite likely to produce a very different loop and/or an incorrect one. In normal cases, looping on a copy of the container helps, but in your case it's clear that you don't want that, as the container will be empty after 50 legs of the loop and if you then try popping again you'll get an exception.
What's anything BUT clear is, what behavior are you trying to achieve, if any?! Maybe you can express your desires with a while...?
i = 0
while i < len(some_list):
print i,
print some_list.pop(0),
print some_list.pop(0)
I've been bitten before by (someone else's) "clever" code that tries to modify a list while iterating over it. I resolved that I would never do it under any circumstance.
You can use the slice operator mylist[::3] to skip across to every third item in your list.
mylist = [i for i in range(100)]
for i in mylist[::3]:
print(i)
Other points about my example relate to new syntax in python 3.0.
I use a list comprehension to define mylist because it works in Python 3.0 (see below)
print is a function in python 3.0
Python 3.0 range() now behaves like xrange() used to behave, except it works with values of arbitrary size. The latter no longer exists.
The general rule of thumb is that you don't modify a collection/array/list while iterating over it.
Use a secondary list to store the items you want to act upon and execute that logic in a loop after your initial loop.
Use a while loop that checks for the truthfulness of the array:
while array:
value = array.pop(0)
# do some calculation here
And it should do it without any errors or funny behaviour.
Try this. It avoids mutating a thing you're iterating across, which is generally a code smell.
for i in xrange(0, 100, 3):
print i
See xrange.
I guess this is what you want:
l = range(100)
index = 0
for i in l:
print i,
try:
print l.pop(index+1),
print l.pop(index+1)
except IndexError:
pass
index += 1
It is quite handy to code when the number of item to be popped is a run time decision.
But it runs with very a bad efficiency and the code is hard to maintain.
This slice syntax makes a copy of the list and does what you want:
l = range(100)
for i in l[:]:
print i,
print l.pop(0),
print l.pop(0)
Here's my code
def abc(l,z):
L=[]
länge= len(L)
for x in range(0, länge+1):
L[x]+z
print(L)
abc(["1","2","3"],"-")
I want the program to output "1-2-3"
l in abc(l,z) should be a List out of Strings which combines "l" and "z" to a single String.
I'm getting an Index Error: list index out of range.
There are a couple of issues here.
First, range(0, länge+1) will stop at länge but your list only has indexes from 0 tolänge - 1, so that's one source for an IndexError.
Second, L[x]+z will give you another IndexError because L is empty but you try to access L[0] (and in the next iteration, where you don't get because of the error, L[1], L[2], and so on).
Third, even without an IndexError the statement L[x]+z will do nothing. You compute the value of L[x]+z but then you don't assign any variable to it, so it is immediately lost.
Fourth, in order to print your final result, put the call to print after the for loop, not inside. Consider using return instead of print if you actually want to do something with the result the function produces (make sure to educate yourself on the difference between print and return).
Fifth, you want to build a string, so the usage of the list L does not make much sense. Start with an empty string and add the current item from l and z to it in the loop body (coupled with a re-assignment in order to not lose the freshly computed value).
Lastly, there's no point in using range here. You can iterate over values in a list direclty by simply writing for x in l:.
That should give you enough to work with and fix your code for now.
(If you don't care why your function does not work and this is not an exercise, simply use str.join as suggested in the comments.)
I am currently writing a small bit of logic for my HTML page. My aim is to create variables (lists) within an iteration (using the iteration to create the names of said lists as the amount of them will be unknown to the program). I am currently creating the lists like this:
maps={}
currentMap = elements[0].process
counter=0
for i in elements:
if(counter==0):
maps["mapsEle{0}".format(counter)]=[]
counter+=1
if(i.process!=currentMap):
currentMap = i.process
maps["mapEle{0}".format(counter)]=[]
counter+=1
else:
print("No change found, keeping heading the same.")
However as you can probably tell, this does not create a list but a string. I try to print the variables (e.g. mapsEle0) and it returns the variable name (e.g. print(mapsEle0) returns "mapsEle0") this too me is suprising as I would have thought if the dictionary is saving it as a string it would print "[]".
So I am looking for a way to create lists within the dictionary in that iteration I am using there, basically want to just reformat my declaration. Cheers in advance everyone :)
Edit:
As requested here is the code where I attempt to append. Please note I want to append 'i' into the lists and no the dictionary.
for i in maps:
for x in elements:
if(x.process!=currentMap):
currentMap=x.process
elif(x.process==currentMap):
#i.append(x)
The syntax of your print statement is wrong, if you want to access the contents of the dictionary, you need to use different notation.
Instead of print('mapsEle0') you need to do print(maps['mapsEle0']).
Update:
Unfortunately your description of what you want and your code are a bit conflicting, so if you can, please try to explain some more what this code is supposed to do.
for i in maps.iterkeys():
for x in elements:
if(x.process!=currentMap):
currentMap=x.process
elif(x.process==currentMap):
maps[i].append(x)
This will iterate over all keys of maps ('mapsEle0'...'mapsEleN') and add x to the contained list if the elif condition is fulfilled.
You're printing the string by doing print('mapsEle0').
To print the dict, you must print(maps) - 'll print the whole dictionary, OR, to print a specific key/element print(maps['mapsEle0'])
To elaborate it further here's a interpreter session:
>>> maps = {}
>>> counter = 0
>>> maps["mapsEle{0}".format(counter)]=[]
>>> maps
{'mapsEle0': []}
>>>
>>> print(maps)
{'mapsEle0': []}
>>>
>>> print(maps['mapsEle0'])
[]
>>>
For the append part:
>>> maps['mapsEle1'].append('hello')
>>> print(maps['mapsEle1'])
['hello']
Edit 2: Your statement is still not clear
As requested here is the code where I attempt to append. Please note I
want to append 'i' into the lists and no the dictionary.
I think sobek has got it right - you want to append x to the mapsEle0, mapsEle1 lists, which are keys in maps dictionary.
for i in maps.iterkeys():
for x in elements:
if(x.process!=currentMap):
currentMap=x.process
elif(x.process==currentMap):
maps[i].append(x)
I am writing a piece of code the this is the scenario I am facing.
How to update the list which is in for-condition, and for the next iteration, the list in for-condition is updated?
Eg.,
list = [0,1,2]
for i in list:
print list[i]
if list[i] == 0:
list.append(3)
The entry '3' should get updated in the list in for-condition.
Is it possible to update the list in for-condition dynamically?
Thanks in advance.
Yes, if you do that, it will work. However, it's usually not a good idea, because it can create confusing interactions between the iteration and the loop-body action. In your example, you add an element at the end, but if, for instance, you change an element in the middle, you may or may not see the change depending on where you are in the list when it happens. (For instance, you could change the value of an element you already iterated past.)
Also, you shouldn't name a variable list, as that shadows the built-in type called list.
Be aware that your loop is incorrect, in Python this snippet:
for e in lst:
… Iterates over each element e in lst, and e is not an index, it's an element - so all the parts in the question where you wrote list[i] are incorrect, they should have been simply i. Try this solution instead, it's equivalent and less error prone:
lst = [0, 1, 2]
print(lst)
lst += [3] * lst.count(0) # add as many 3s at the end as there are 0s in the list
Notice that it's never a good idea to modify a list at the same time you're traversing it. Also, don't use list as a variable name, there's a built-in function with that name.
for example, if i have a list like:
one = [1,2,3]
what function or method can i use to split each element into their own separate list like:
one = [1]
RANDOM_DYNAMIC_NAME = [2]
RANDOM_DYNAMIC_NAME_AGAIN = [3]
and at any given time, the unsplit list called one may have more than 1 element, its dynamic, and this algorithm is needed for a hangman game i am coding as self-given homework.
the algorithm is needed to complete this example purpose:
pick a word: mississippi
guess a letter: s
['_','_','s','s','_','s','s','_','_','_','_']
Here is my code:
http://pastebin.com/gcCZv67D
Looking at your code, if the part you're trying to solve is the comments in lines 24-26, you definitely don't need dynamically-created variables for that at all, and in fact I can't even imagine how they could help you.
You've got this:
enum = [i for i,x in enumerate(letterlist) if x == word]
The names of your variables are very confusing—something called word is the guessed letter, while you've got a different variable letterguess that's something else, and then a variable called letter that's the whole word… But I think I get what you're aiming for.
enum is a list of all of the indices of word within letterlist. For example, if letterlist is 'letter' and word is t, it will be [2, 3].
Then you do this:
bracketstrip = (str(w) for w in enum)
So now bracketstrip is ['2', '3']. I'm not sure why you want that.
z = int(''.join(bracketstrip))
And ''.join(bracketstrip) is '23', so z is 23.
letterguess[z] = word
And now you get an IndexError, because you're trying to set letterguess[23] instead of setting letterguess[2] and letterguess[3].
Here's what I think you want to replace that with:
enum = [i for i,x in enumerate(letterlist) if x == word]
for i in enum:
letterguess[i] = word
A few hints about some other parts of your code:
You've got a few places where you do things like this:
letterlist = []
for eachcharacter in letter:
letterlist.append(eachcharacter)
This is the same as letterlist = list(letter). But really, you don't need that list at all. The only thing you do with that is for i, x in enumerate(letterlist), and you could have done the exact same thing with letter in the first place. You're generally making things much harder for yourself than you have to. Make sure you actually understand why you've written each line of code.
"Because I couldn't get it to work any other way" isn't a reason—what were you trying to get to work? Why did you think you needed a list of letters? Nobody can keep all of those decisions in their head at once. The more skill you have, the more of your code will be so obvious to you that it doesn't need comments, but you'll never get to the point where you don't need any. When you're just starting out, every time you figure out how to do something, add a comment reminding yourself what you were trying to do, and why it works. You can always remove comments later; you can never get back comments that you didn't write.
for question one ,just list comprehension is good . it will return each element as a separate list
[ [x,] for x in one ]
As for a literal answer to your question, here's how you do it, though I can't immagine why you would want to to this. Generally, dynamic variable names are poor design. You probably just want a single list, or list of lists.
import random
for x in one:
name = 'x' + str(random.getrandbits(10))
globals()[name] = [x]