我有一个值列表,现在说元组,例如
tmis = [
( 'script1', 'function1', 'lock1' ),
( 'script1', 'function2', 'lock1' ),
( 'script1', 'function3', 'lock1' ),
( 'script2', 'function4', 'lock1' ),
( 'script3', 'function5', 'lock2' ),
( 'script4', 'function6', 'lock3' ),
( 'script5', 'function7', 'lock3' ),
( 'script8', 'function10', 'lock1, lock2' )
]
我希望使用相同的“脚本”对数据进行分组,但使用不同的“锁定”。
期望的输出:
[
[('script1', 'function1', 'lock1'),
('script1', 'function2', 'lock1'),
('script1', 'function3', 'lock1'),
('script3', 'function5', 'lock2'),
('script4', 'function6', 'lock3')],
[('script2', 'function4', 'lock1'),
('script5', 'function7', 'lock3')],
[('script8', 'function10', 'lock1, lock2')]
]
所以这个数据的输出是3组,其中每组只有1个特定“锁定”的出现,但是如果它们具有相同的“脚本”值,那么它们可以放在同一组中而不管多次出现相同的'锁'。最后一个数据项'script8'也有2个'锁',因此应该在没有现有'lock1'或'lock2'的组中。
它不一定是这种格式,我可以使用dictionary / set / tuples / list /其他。我找到了一种方法,但它不漂亮,所以想知道是否有一个简单的简单方法来进行这种分组。
我尝试过(从其他解决方案中找到)
groups = []
uniquekeys = []
data = sorted(tmis, key=lambda x: x[0] )
for k, g in itertools.groupby(data, lambda x: x[0]):
groups.append( list(g) )
uniquekeys.append(k)
但这只是按'script'值组合。有什么想法吗?
编辑:我想我的解释不是很清楚。我想要做的是将元组分组,使得没有两个具有相同“锁定”的“脚本”在同一组中(除非“脚本”是相同的)
如果它有帮助,我可以发布我当前(丑陋)的解决方案。
答案 0 :(得分:1)
您的示例与您提供的说明不符。例如,s3,l2和s4,l3与s1,l1在同一组中。
假设你只想做你在文中所说的而不是你想要的输出。这是代码 -
tmis = [
( 's1', 'm1', 'l1' ),
( 's1', 'm2', 'l1' ),
( 's1', 'm3', 'l1' ),
( 's2', 'm4', 'l1' ),
( 's1', 'm5', 'l2' ),
( 's4', 'm6', 'l3' ),
( 's5', 'm7', 'l3' ),
( 's8', 'm10', 'l1, l2' )
]
d={}
for i in tmis:
flag=0
if d.has_key(i[2]):
d[i[2]].append(i)
flag=1
else:
for key in d.keys():
if d[key][0][0] == i[0]:
d[key].append(i)
flag=1
break
if flag==0:
d[i[2]] = []
d[i[2]].append(i)
print d
答案 1 :(得分:0)
这是我的解决方案:
def getscript(group, lock):
"""
returns the script used by the given lock in the given group
or None if no script uses the given lock
"""
for script, function, locks in group:
if lock in locks.split(', '):
return script
return None
def compatible(group, task):
"""
tells if a task ((script, function, locks) tuple) can be added to a group
"""
for lock in task[2].split(', '):
script = getscript(group, lock)
if script and script != task[0]:
return False
return True
def makegroups(tasks):
groups = []
for task in tasks:
try:
group = next(grp for grp in groups if compatible(grp, task))
except StopIteration:
groups.append([task])
else:
group.append(task)
return groups