我有一个名为person的对象列表及其国家/地区:
class Person(object):
def __init__(self, id, country):
self.id = str(id)
self.country = str(country)
列表如下所示,其中id仅为UUID,国家/地区为国家/地区代码,我按国家/地区对其进行了排序:
('7e569521-69fe-4ccf-a898-254bd758bff0', 'AF')
('c6b45478-6901-4a22-aab8-7167397d4b13', 'AF')
('15aee743-a1b1-4a77-b93b-17786c8c8fab', 'AF')
('7ef1efd3-6b77-4dfe-b133-035eff76d7f6', 'AF')
('95880e05-9984-48e3-a60a-0cf52c2915ae', 'AG')
('620862a0-e888-4b20-8057-085122226050', 'AL')
('ed0caf58-e132-48ad-bfca-8a4df2b0c351', 'AL')
('730cf6ba-0981-4a0b-878e-5df0ebedaa99', 'AM')
('93f87a3d-d618-4e9a-9f44-4a1d0bc65bdc', 'AM')
现在我想按国家/地区将它们分成不同的列表。
这就是我现在正在做的事情:
prev_country = ""
person_data_country = []
for person in persons_data:
if prev_country != person.country:
if len(person_data_country) > 0:
# do something with this new list by country
# clear them
person_data_country = []
# append item to new list
person_data_country.append(person)
prev_country = person.country
# last list, if any
if len(person_data_country) > 0:
# do something with this new list by country
我通过上述代码得到了我想要的东西。
但我想知道是否有更好或更有效的方法根据国家/地区拆分列表?
答案 0 :(得分:4)
您可以使用itertools.groupby
(https://docs.python.org/3.6/library/itertools.html#itertools.groupby)来实现您的目标:
from itertools import groupby
grouped_data = groupby(persons_data, key=lambda x: x[1]) # or x.country, depending on your input list
for country, items in grouped_data:
# do whatever you want
要记住一些问题:
groupby
返回一个迭代器,因此您只能迭代一次。items
也是一个迭代器。因此,如果您希望稍后通过索引访问各个项目,则需要将其强制转换为列表。答案 1 :(得分:2)
您可以使用itertools.groupby。鉴于persons_data
已经按国家/地区排序,以下代码可以执行您想要的操作:
import itertools
import operator
bycountry = operator.attrgetter("country")
all_people_by_country = []
for country, groupiter in itertools.groupby(persons_data, bycountry):
all_people_by_country.append(list(groupiter))
答案 2 :(得分:1)
考虑我是否正确理解你的另一种方法:
from collections import defaultdict
persons = [
Person('one', 'AF'),
Person('two', 'AF'),
Person('three', 'AG')
]
persons_by_country = defaultdict(list)
for person in persons:
persons_by_country[person.country].append(person.id)
或者,如果您出于某种原因想要避免defaultdict
,
persons_by_country = {}
for person in persons:
if person.country in persons_by_country:
persons_by_country[person.country].append(person.id)
else:
persons_by_country[person.country] = [person.id]
无论哪种方式,结果都是:
{'AG': ['three'], 'AF': ['one', 'two']}
这方面的主要缺点是所有数据都存储在内存中两次。