Python查找并替换列表中的最后一个外观

时间:2016-09-07 15:49:28

标签: python list

在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')]

3 个答案:

答案 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. 使用https://stackoverflow.com/a/952952/2988730
  2. 展平列表
  3. 找到独特的元素
  4. 查找每个唯一元素最后一次出现的索引(通过反转列表)
  5. 更新元素
  6. 使用https://stackoverflow.com/a/10124783/2988730
  7. 重新整理扁平化列表

    以下是一个示例实现:

    # 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()