关于python:zip()和zip(*)似乎给出了类似的结果

zip() and zip(*) seem to give similar results

本问题已经有最佳答案,请猛点这里访问。

我试图理解zip()zip(*)之间的区别。

据我所知,zip()可以用来组合两个列表,这样具有共享索引的元素就可以在一起。例如,在这些示例中:

1
2
3
4
5
6
7
8
9
10
11
12
13
dict_list = {'First Name': ['Tom', 'Ann', 'Ben'],
             'Last Name': ['Haverford', 'Perkins', 'Wyatt'],
             'Age': [33, 42, 44],
             'Occupation': ['Administrator', 'Nurse', 'Auditor']}

for first_name, last_name, age, occupation in zip(dict_list['First Name'], dict_list['Last Name'], dict_list['Age'], dict_list['Occupation']):
             print(first_name, last_name, age, occupation)

#result    

Tom Haverford 33 Administrator
Ann Perkins 42 Nurse
Ben Wyatt 44 Auditor

那么,为什么在我看来,有时候,zip(*)的行为是这样的呢?例如:

1
2
3
4
5
6
7
for t in (zip(*dict_list.values())):
    print(t)
#result    

('Tom', 'Haverford', 33, 'Administrator')
('Ann', 'Perkins', 42, 'Nurse')
('Ben', 'Wyatt', 44, 'Auditor')

由于我的dict_list.values()是列表,所以看起来zip(*)将所有具有共享索引的元素放在同一个元组中。这与第一个代码没有太大的区别,在第一个代码中,我在for循环中使用zip(),其中传递了dict键并带有相应的循环变量

在这种情况下,zip()zip(*)的表现如何?


1
2
>>> dict_list.values()
[['Tom', 'Ann', 'Ben'], ['Haverford', 'Perkins', 'Wyatt'], [33, 42, 44], ['Administrator', 'Nurse', 'Auditor']]

这将返回包含四个子列表的列表。

1
zip(*dict_list.values())

这会解包该列表,并将每个元素作为单独的参数传递给zip()。这就是*解包操作符所做的:如果您使用包含四个元素的列表l调用zip(*l),它使用这四个参数调用zip()

将它与您编写的第一个片段进行比较,后者将dict_list中的四个列表作为单独的参数传递给zip

1
zip(dict_list['First Name'], dict_list['Last Name'], dict_list['Age'], dict_list['Occupation'])

他们两个最终都将相同的东西传递给了zip()。当然,结果是一样的。

如果要将其与不带*的版本进行比较,请尝试:

1
zip(dict_list.values())

现在有一个区别:

1
2
3
4
>>> zip(*dict_list.values())
[('Haverford', 'Tom', 33, 'Administrator'), ('Perkins', 'Ann', 42, 'Nurse'), ('Wyatt', 'Ben', 44, 'Auditor')]
>>> zip(dict_list.values())
[(['Haverford', 'Perkins', 'Wyatt'],), (['Tom', 'Ann', 'Ben'],), ([33, 42, 44],), (['Administrator', 'Nurse', 'Auditor'],)]