1

我有

(('A', '1', 'UTC\xb100:00'), ('B', '1', 'UTC+01:00'), ('C', '1', 'UTC+02:00'), ('D', '1', 'UTC+01:00'), ('E', '1', 'UTC\xb100:00'), ('F', '1', 'UTC+03:00'))

并且想

  (('A','E, '1', 'UTC\xb100:00'), ('B','D', '1', 'UTC+01:00'), ('C', '1', 'UTC+02:00'), ('F', '1', 'UTC+03:00'))

我已经看到您可以使用列表来执行此操作,但我还没有看到使用 turple 完成此操作..这可能吗..?

4

5 回答 5

1

您可以使用groupby,但您需要先对输入进行排序,如下所示:

from itertools import groupby
from operator import itemgetter

l = (('A', '1', 'UTC\xb100:00'), ('B', '1', 'UTC+01:00'), ('C', '1', 'UTC+02:00'), ('D', '1', 'UTC+01:00'), ('E', '1', 'UTC\xb100:00'), ('F', '1', 'UTC+03:00'))

result = []
key_items = itemgetter(1, 2)
for key, group in groupby(sorted(l, key=key_items), key=key_items):
    item = []
    item.extend([k[0] for k in group])
    item.extend(key)
    result.append(tuple(item))

print tuple(result)

此代码打印:

(('B', 'D', '1', 'UTC+01:00'), ('C', '1', 'UTC+02:00'), ('F', '1', 'UTC+03:00'), ('A', 'E', '1', 'UTC\xb100:00'))

没那么美,我理解。

于 2013-08-04T18:35:21.923 回答
0

如果您只关心具有相同代码的项目在同一个元组中,那么这个答案有效:

nodup = {}
my_group_of_items = (('A', '1', 'UTC\xb100:00'), ('B', '1', 'UTC+01:00'), ('C', '1', 'UTC+02:00'), ('D', '1', 'UTC+01:00'), ('E', '1', 'UTC\xb100:00'), ('F', '1', 'UTC+03:00'))
for r in my_group_of_items:
    if r[-1] not in nodup: nodup[r[-1]] = set()
    nodup[r[-1]] |= set(r[:-1])

result = [ tuple(list(nodup[t])+[t]) for t in nodup ]
print result
于 2013-08-04T21:25:09.423 回答
0

为此使用pandas可能有点矫枉过正,但您可以:

import pandas as pd

# somehow, pandas 0.12.0 does prefers 
# a list of tuples rather than a tuple of tuples
t = [('A', '1', 'UTC\xb100:00'), 
     ('B', '1', 'UTC+01:00'), 
     ('C', '1', 'UTC+02:00'), 
     ('D', '1', 'UTC+01:00'), 
     ('E', '1', 'UTC\xb100:00'), 
     ('F', '1', 'UTC+03:00')]

df = pd.DataFrame(t, columns=('letter', 'digit', 'tz'))
grouped = df.groupby('tz')

print(grouped.groups)

# {'UTC+01:00': [1, 3],
#  'UTC+02:00': [2],
#  'UTC+03:00': [5],
#  'UTC\xb100:00': [0, 4]}

merged = []
for key, vals in grouped.groups.iteritems():
    update = [ t[idx][0] for idx in vals ] # add the letters
    update += t[idx][1:] # add the digit and the TZ
    merged.append(update)

print(merged)
# [['F', '1', 'UTC+03:00'], ['C', '1', 'UTC+02:00'], \
#  ['A', 'E', '1', 'UTC\xb100:00'], ['B', 'D', '1', 'UTC+01:00']]

优点是相当简洁df.groupby('tz'),缺点是相当重的依赖(pandas 加上它的依赖)。

可以将合并压缩为一条不太容易理解的行:

merged = [[t[idx][0] for idx in vs] + list(t[idx][1:])
            for vs in grouped.groups.values()]
于 2013-08-04T18:32:39.413 回答
0

您可以使用理解,但仍然有点复杂。

tuples = (('A', '1', 'UTC\xb100:00'), ('B', '1', 'UTC+01:00'), ('C', '1', 'UTC+02:00'), ('D', '1', 'UTC+01:00'), ('E', '1', 'UTC\xb100:00'), ('F', '1', 'UTC+03:00'))

>>values = set(map(lambda x:x[1:3], tuples))
set([('1', 'UTC+03:00'), ('1', 'UTC\xb100:00'), ('1', 'UTC+01:00'), ('1', 'UTC+02:00')])

>>f = [[y[0] for y in tuples if y[1:3]==x] for x in values]
[['F'], ['A', 'E'], ['B', 'D'], ['C']]

>>r = zip((tuple(t) for t in f), values)
[(('F',), ('1', 'UTC+03:00')), (('A', 'E'), ('1', 'UTC\xb100:00')), (('B', 'D'), ('1', 'UTC+01:00')), (('C',), ('1', 'UTC+02:00'))]

>>result = tuple([sum(e, ()) for e in r])
(('F', '1', 'UTC+03:00'), ('A', 'E', '1', 'UTC\xb100:00'), ('B', 'D', '1', 'UTC+01:00'), ('C', '1', 'UTC+02:00'))

把它放在一起:

values = set(map(lambda x:x[1:3], tuples))
f = [[y[0] for y in tuples if y[1:3]==x] for x in values]
r = zip((tuple(t) for t in f), values)
result = tuple([sum(e, ()) for e in r])
于 2013-08-04T19:14:40.313 回答
0

对于元组,您不能修改内容,但您可以例如连接元组以获取其他元组。

def process(data):
    res = []
    for L in sorted(data, key=lambda x:x[2][-5:]):
        if res and res[-1][2][-5:] == L[2][-5:]:
            # Same group... do the merge
            res[-1] = res[-1][:-2] + (L[0],) + res[-1][-2:]
        else:
            # Different group
            res.append(L)
    return res

在我看来,最终结果更像是一个列表(逻辑上同质的内容)而不是一个元组,但如果你真的需要一个元组,你可以return tuple(res)代替。

于 2013-08-04T19:31:48.587 回答