问题
I am having some trouble getting expected results out of the zip command. Cases 1-3 make sense, but in cases 4 and 5 (which I assume are equivalent?) I expect the results to be [['a'],['b'],['c'],['d']], but instead the entirety of the second list is appended to each sublist of the list of lists I initialize.
Case 1:
>>> for a in zip([1,2,3,4],['a','b','c','d']):
... print a
(1, 'a')
(2, 'b')
(3, 'c')
(4, 'd')
Case 2:
>>> for (a,b) in zip([1,2,3,4],['a','b','c','d']):
... print a,b
...
1 a
2 b
3 c
4 d
Case 3:
>>> temp = [[]] * 4
>>> for (a,b) in zip([0,1,2,3],['a','b','c','d']):
... temp[a] = b
...
>>> temp
['a', 'b', 'c', 'd']
Case 4:
>>> temp = [[]] * 4
>>> for (a,b) in zip([0,1,2,3],['a','b','c','d']):
... temp[a].append(b)
...
>>> temp
[['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd']]
Case 5:
>>> temp = [[]] * 4
>>> for a,b in zip([0,1,2,3],['a','b','c','d']):
... temp[a].append(b)
...
>>> temp
[['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd']]
回答1:
You've run into the way Python deals with variable names and references. It can be confusing if you have worked with C-style languages before, but makes a lot of sense if you don't think that way!
Python has "things" and "names for things". For example, x
is a name, []
is a thing, and x=[]
assigns the name x
to the thing []
.
The list multiplication syntax is a bit confusing with regards to names and things. Let's expand it out to see how it works:
name = [x]*4
is the same as
_temp = x name = [_temp, _temp, _temp, _temp]
With that in mind, the following code should make sense:
>>> x = []
>>> y = [x]*4
>>> y[0].append(1)
>>> y
[[1], [1], [1], [1]]
Why? Well, when you write y=[x]*4]
you make a list of four names. But those are all names for the same thing! If you .append(1)
to the object named by the first name, you change the object that all the names, well, name.
Now, just as before,
name = [[]]*4
is the same as
_temp = [] name = [_temp, _temp, _temp, _temp]
You haven't explicitly created a new name. But you have done so implicitly! You only call []
once, so you only make one new list. You then make a list of four names, each of the new empty list you just made. So it should come as no surprise that all the names name the same thing!
How to fix this, you say? Well, you need to call []
once for each new list that you want. To do that, use a list comprehension:
[[] for _ in range(4)]
Note that _
is just another name, although it is conventionally used for things you don't care about.
回答2:
[[]] * 4
creates a list of references to the single object:
>>> l = [[]] * 4
>>> l
[[], [], [], []]
>>> l[0].append(1)
>>> l
[[1], [1], [1], [1]]
Try [[] for _ in range(4)]
instead.
回答3:
temp = [[]] * 4
This creates a list that contains four references to the same list object. You only have one "sublist" that is contained four time in the "master list". It's the same situation as in this example:
>>> ls = []
>>> tmp = [ls, ls, ls, ls]
>>> ls.append(1)
>>> tmp
[[1], [1], [1], [1]]
You probably wanted to use separate list objects for your list elements. Such a list could for example be created this way:
tmp = [[] for _ in range(4)]
回答4:
It's because when you create temp = [[]]*4, you create a list with 4 references to the same (empty) list.
来源:https://stackoverflow.com/questions/9760530/use-python-to-loop-over-two-lists-using-one-as-an-index-to-a-list-of-lists-and