我有这样的元组
[
(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)
]
我想改为:
[
(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)))
]
所以对于任何元素,任何不是第一个元素的东西都在它的子元组内,如果下面的元素与第一个元素具有相同的元素,它将被设置为前一个元素的另一个子元组之一。
所以我能做到:
for i in data:
# getting the first element of the list
for sub_i in i[1]:
# i access all the tuples inside
是否有一些功能可以做到这一点?
答案 0 :(得分:4)
defaultdict
非常简单;您将默认值初始化为列表,然后将该项追加到相同键的值:
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)])]
如果订单很重要,请使用可以记住广告订单的OrderedDict
:
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]])]
答案 1 :(得分:1)
您可以使用Python3变量解压缩和OrderedDict
来保留顺序:
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()]
输出:
[(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 :(得分:1)
使用itertools.groupby
(和operator.itemgetter
获取第一项)。唯一的事情是您的数据需要已经排序,以便这些组一个接一个地显示(如果您使用过uniq
和sort
bash命令,则是相同的想法),则可以使用{ {3}}为此
import operator
from itertools import groupby
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),
]
data = sorted(data, key=operator.itemgetter(0)) # this might be unnecessary
for k, g in groupby(data, operator.itemgetter(0)):
print(k, list(g))
将输出
4746004 [(4746004, 'it', 28, 2, 2, 'NON ENTRARE', 'NonEntrate', 26, 2), (4746004, 'it', 28, 2, 2, 'TheBestTroll Group', 'TheBestTrollGroup', 2, 3)]
379146591 [(379146591, 'it', 55, 1, 1, 'NON ENTRARE', 'NonEntrate', 55, 1)]
对于您而言,还需要从值列表中删除第一个元素。将上面的最后两行更改为:
for k, g in groupby(data, operator.itemgetter(0)):
print(k, [item[1:] for item in g])
输出:
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)]
答案 3 :(得分:0)
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))