问题
i have a tuple like this
[
(379146591, 'it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1),
(4746004, 'it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2),
(4746004, 'it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)
]
i would like to get instead this:
[
(379146591, (('it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1)),
(4746004, (('it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2), ('it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)))
]
so the for any element, anything that is not the first element is inside a sub-tuple of it, and if the following element has the same element as first element, it will be set as another sub-tuple of the previous one.
so i can do:
for i in data:
# getting the first element of the list
for sub_i in i[1]:
# i access all the tuples inside
are there some functions to do this?
回答1:
It's pretty simple with defaultdict
; You initialize the default value to be a list and then append the item to the value of the same key:
lst = [
(379146591, 'it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1),
(4746004, 'it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2),
(4746004, 'it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)
]
from collections import defaultdict
d = defaultdict(list)
for k, *v in lst:
d[k].append(v)
list(d.items())
#[(4746004,
# [('it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2),
# ('it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)]),
# (379146591, [('it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1)])]
If order is important, use an OrderedDict
which can remember the insertion orders:
from collections import OrderedDict
d = OrderedDict()
for k, *v in lst:
d.setdefault(k, []).append(v)
list(d.items())
#[(379146591, [['it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1]]),
# (4746004,
# [['it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2],
# ['it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3]])]
回答2:
You can use Python3 variable unpacking and OrderedDict
to retain order:
from collections import OrderedDict
d = OrderedDict()
l = [
(379146591, 'it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1),
(4746004, 'it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2),
(4746004, 'it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)
]
for a, *b in l:
if a in d:
d[a].append(b)
else:
d[a] = [b]
final_data = [(a, tuple(map(tuple, b))) for a, b in d.items()]
Output:
[(379146591, (('it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1),)), (4746004, (('it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2), ('it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)))]
回答3:
u can use collection.defaultdict:
data = [
(379146591, 'it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1),
(4746004, 'it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2),
(4746004, 'it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)
]
from collections import defaultdict
a = defaultdict(list)
a = defaultdict(list)
from collections import defaultdict
a = defaultdict(list)
for d in data:
a[d[0]].append(d[1:])
for k,v in a.items():
a[k] = tuple(a[k])
print(dict(a))
来源:https://stackoverflow.com/questions/46493056/python-group-elements-of-a-tuple-having-the-same-first-element