How to rename an element of a sublist when the sublist is repeated several times?

时间:2017-06-09 12:44:19

标签: python python-2.7 python-3.x

This is what I have: A list which contains sublists

A= [['filename.yaml','0001'],['filename.yaml','0001'],['filename.yaml','0001'], ['fname.yaml','0002'], ['fname.yaml','0002']]

What i want is to rename the first element of each sublist when the sublist is present more than once. The out put should be:

[['filename_0.yaml','0001'],['filename_1.yaml','0001'],['filename_2.yaml','0001'], ['fname_0.yaml','0002'], ['fname_1.yaml','0002']]

This is my code:

def asso_name_id(A):

for sublist in A:
    if A.count(sublist)>1:
        for i in range(A.count(sublist)):
            base=os.path.splitext(os.path.basename(sublist[0]))[0]
            sublist[0]=base+"_"+str(i)+'.yaml'

This is what i get with this code:

[['filename_0_1_2.yaml', '0001'], ['filename_0_1.yaml', '0001'], ['filename.yaml', '0001'], ['fname_0_1.yaml', '0002'], ['fname.yaml', '0002']]

What am I doing wrong and how can I fix it?

4 个答案:

答案 0 :(得分:0)

你可以试试这个:

from itertools import chain
A= [['filename.yaml','0001'],['filename.yaml','0001'],['filename.yaml','0001'], ['fname.yaml','0002'], ['fname.yaml','0002']]

flattened = list(chain(*A))

new_dict = {}

for i in A:
    if i[0] not in new_dict:
        new_dict[i[0]] = 1

    else:
        new_dict[i[0]] += 1

final_list = []

for i in A:
    first = i[0].split(".")
    new = first[0]+"_"+str(abs(new_dict[i[0]]-flattened.count(i[0])))
    final_list.append([new+first[1], i[1]])

    new_dict[i[0]] -= 1

print final_list

输出:

[['filename_0yaml', '0001'], ['filename_1yaml', '0001'], ['filename_2yaml', '0001'], ['fname_0yaml', '0002'], ['fname_1yaml', '0002']]

答案 1 :(得分:0)

在每个子列表中,您要检查有多少相同的子列表,然后在同一子列表中重复x次操作。这就是为什么第二个只做两次,因为第一个不再相同,所以它只检测2个相同的子列表。相反,试试这个:

#!/usr/bin/python3 
import os
A= [['filename.yaml','0001'],['filename.yaml','0001'],['filename.yaml','0001'], ['fname.yaml','0002'],['fname.yaml','0002']]

def asso_name_id(A):

  for sublist in A
    if A.count(sublist) > 1:
            sublist_name = (sublist[0]+'.')[:-1]
            count = 0
            for s_list in A:
                if s_list[0] == sublist_name:
                        base=os.path.splitext(os.path.basename(s_list[0]))[0]
                        s_list[0]= base+"_"+str(count)+".yaml"
                        count += 1
  return A

print(asso_name_id(A))

输出:

[['filename_0.yaml', '0001'], ['filename_1.yaml', '0001'], ['filename_2.yaml', '0001'], ['fname_0.yaml', '0002'], ['fname_1.yaml', '0002']]

答案 2 :(得分:0)

first = map(lambda (first, second): first, A)
second = map(lambda (first, second): second, A)
zip([item for sublist in [map(lambda inc: key + "_" + str(inc), range(value)) for key, value in Counter(first).iteritems()] for item in sublist], second)

不是一个完整的解决方案。还需要在yaml上进行字符串拆分。运作顺序 1.只获取文件名 2.只获得&#39; 000X 3.计算文件名 4.为每个文件名创建一个带有_Y的新文件名,其中Y <=出现次数(使用Counter类) 5.用2)拉

答案 3 :(得分:0)

使用列表推导

的简单解决方案
import collections
import itertools as IT

A= [['filename.yaml','0001'],['filename.yaml','0001'],['filename.yaml','0001'], ['fname.yaml','0002'], ['fname.yaml','0002']]

counter1 = IT.count(0)
counter2 = IT.count(0)

A = [['filename_{0}.yaml'.format(next(counter1)),sub_list[1]] 
       if sub_list[0]=='filename.yaml' else ['fname_{0}.yaml'.format(next(counter2)),sub_list[1]] 
       for sub_list in A ]

print(A)

输出:

[['filename_0.yaml', '0001'], ['filename_1.yaml', '0001'], ['filename_2.yaml', '0001'], ['fname_0.yaml', '0002'], ['fname_1.yaml', '0002']]

列出理解解释

对于A中的每个列表(sub_list),如果 sub_list [0] 即sub_list的第一个元素是&#39; filename.yaml&#39;然后将其格式化为&#39; filename_ {0} .yaml&#39; 否则&#39; fname_ {0} .yaml&#39; 其中{0}将保留我们的变量计数器。

使用从0开始的计数器并使用 next()来递增计数器。

注意:使用两个计数器。