在Python中,我有一个列表
list3 = ['PA0', 'PA1']
list2 = ['PB0', 'PB1']
list1 = ['PC0', 'PC1', 'PC2']
[(list1[i], list2[j], list3[k]) for i in xrange(len(list1)) for j in xrange(len(list2)) for k in xrange(len(list3))]
#Result
[('PC0', 'PB0', 'PA0'),
('PC0', 'PB0', 'PA1'),
('PC0', 'PB1', 'PA0'),
('PC0', 'PB1', 'PA1'),
('PC1', 'PB0', 'PA0'),
('PC1', 'PB0', 'PA1'),
('PC1', 'PB1', 'PA0'),
('PC1', 'PB1', 'PA1'),
('PC2', 'PB0', 'PA0'),
('PC2', 'PB0', 'PA1'),
('PC2', 'PB1', 'PA0'),
('PC2', 'PB1', 'PA1')]
如何找到最后一次出现并添加 E 作为后缀
[('PC0', 'PB0', 'PA0'), ('PC0', 'PB0', 'PA1'), ('PC0', 'PB1', 'PA0'), ('PC0E', 'PB1', 'PA1'), ('PC1', 'PB0', 'PA0'), ('PC1', 'PB0', 'PA1'), ('PC1', 'PB1', 'PA0'), ('PC1E', 'PB1', 'PA1'), ('PC2', 'PB0', 'PA0'), ('PC2', 'PB0E', 'PA1'), ('PC2', 'PB1', 'PA0E'), ('PC2E', 'PB1E', 'PA1E')]
答案 0 :(得分:2)
反向处理输入列表,然后标记任何值的第一个出现。您可以使用集合列表来跟踪您已经看到的值。完成后反转您构建的输出列表:
>>> seensets = [set() for _ in inputlist[0]]
>>> outputlist = []
>>> for entry in reversed(inputlist):
... newentry = []
... for value, seen in zip(entry, seensets):
... newentry.append(value + 'E' if value not in seen else value)
... seen.add(value)
... outputlist.append(tuple(newentry))
...
>>> outputlist.reverse()
>>> pprint(outputlist)
[('PC0', 'PB0', 'PA0'),
('PC0', 'PB0', 'PA1'),
('PC0', 'PB1', 'PA0'),
('PC0E', 'PB1', 'PA1'),
('PC1', 'PB0', 'PA0'),
('PC1', 'PB0', 'PA1'),
('PC1', 'PB1', 'PA0'),
('PC1E', 'PB1', 'PA1'),
('PC2', 'PB0', 'PA0'),
('PC2', 'PB0E', 'PA1'),
('PC2', 'PB1', 'PA0E'),
('PC2E', 'PB1E', 'PA1E')]
演示:
class ThreadedCanine extends Thread {
private $canine;
public function __construct(Canine $canine) {
$this->canine = $canine;
}
public function run() {
$this->canine->bark();
}
}
$threads = [
new ThreadedCanine(new GoldenRitriever()),
new ThreadedCanine(new Pitbull()),
new ThreadedCanine(new GermanShepherd()),
new ThreadedCanine(new LabradorRetriever()),
];
foreach($threads as $thread) {
$thread->start();
}
foreach($threads as $thread) {
$thread->join();
}
答案 1 :(得分:1)
如果您不想在这里寻找闪电般的速度,可以执行以下操作:
以下是一个示例实现:
# 1
flat = list(reversed([x for group in mylist for x in group]))
# 2
uniq = set(flat)
# 3, 4
for x in uniq:
flat[flat.index(x)] += 'E'
# 5
mylist = list(zip(*[reversed(flat)]*3))
结果:
[('PC0', 'PB0', 'PA0'),
('PC0', 'PB0', 'PA1'),
('PC0', 'PB1', 'PA0'),
('PC0E', 'PB1', 'PA1'),
('PC1', 'PB0', 'PA0'),
('PC1', 'PB0', 'PA1'),
('PC1', 'PB1', 'PA0'),
('PC1E', 'PB1', 'PA1'),
('PC2', 'PB0', 'PA0'),
('PC2', 'PB0E', 'PA1'),
('PC2', 'PB1', 'PA0E'),
('PC2E', 'PB1E', 'PA1E')]
答案 2 :(得分:1)
收集的另一种方法是不断添加索引以便最后出现最后一个索引, itertools.product 也会为您创建初始列表:
from itertools import product
def last_inds(prod):
# the key/value will be overwritten so we always keep the last seen
return {ele: (i1, i2) for i1, prod in enumerate(prod) for i2, ele in enumerate(prod)}
prod = list(product(*(list1, list2, list3)))
# use the indexes to change the last occurrences.
for r, c in last_inds(prod).values():
lst = list(prod[r])
lst[c] += "E"
prod[r] = tuple(lst)
这为您提供了预期的输出:
[('PC0', 'PB0', 'PA0'),
('PC0', 'PB0', 'PA1'),
('PC0', 'PB1', 'PA0'),
('PC0E', 'PB1', 'PA1'),
('PC1', 'PB0', 'PA0'),
('PC1', 'PB0', 'PA1'),
('PC1', 'PB1', 'PA0'),
('PC1E', 'PB1', 'PA1'),
('PC2', 'PB0', 'PA0'),
('PC2', 'PB0E', 'PA1'),
('PC2', 'PB1', 'PA0E'),
('PC2E', 'PB1E', 'PA1E')]
在我的时间上,这是使用数据的最快方法。
In [37]: %%timeit
prod = list(product(*(list1, list2, list3)))
m(prod)
....:
10000 loops, best of 3: 20.7 µs per loop
In [38]: %%timeit
prod = list(product(*(list1, list2, list3)))
for r, c in last_inds(prod).values():
lst = list(prod[r])
lst[c] += "E"
prod[r] = tuple(lst)
....:
100000 loops, best of 3: 12.2 µs per loop
其中m是:
def m(inputlist):
seensets = [set() for _ in inputlist[0]]
outputlist = []
for entry in reversed(inputlist):
newentry = []
for value, seen in zip(entry, seensets):
newentry.append(value + 'E' if value not in seen else value)
seen.add(value)
outputlist.append(tuple(newentry))
outputlist.reverse()