将项目附加到列表并通过递增数字确保唯一名称

时间:2018-02-03 14:05:08

标签: python list sorting split counter

这是一个常见问题,但我没有找到符合我尝试的搜索类型的搜索答案。

我有一个名称相似的项目列表,我想添加一个数字后缀,这样每次,如果存在重复,新项目将增加为唯一。我发现的所有已回答的搜索都没有在字符和数字上分割名称。我需要这样做,因为我不只是在处理原始列表,我想添加一个具有唯一名称的新项目。因此,我提取一个与项目类型匹配的子列表,按字母数字排序,将最后一项拆分为后缀和前缀,将数字后缀增加1,重新设置一个新项目名称并将其附加到原始列表的末尾。一切都很好。也许这不是最有效的方法,但可以接受建议。

说我有现有名单:

mylist = ["point1", "feature1", "point2", "area1", "point3", "feature2", "area2"]

并说如果我添加新项pointfeature项,系统会自动将其重命名为point4feature3

所以我得到了我想要的新字符串名称结果,但我的最终列表从不附加新创建的项目。我哪里错了?

到目前为止,我有这个:

from collections import Counter

mylist = ["point1", "feature1", "point2", "area1", "point3", "feature2", "area2"]

def mysplit(s):
     head = s.rstrip('0123456789')
     tail = s[len(head):]
     return head, tail

# extract items starting with specified string into separate sub list
sublist = [x for x in mylist if x.startswith('point')]
# sort sub list alpha-numerically
sublistSort = sorted(sublist, key=lambda item: (int(item.partition(' ')[0])
                               if item[0].isdigit() else float('inf'), item))
print(sublistSort[-1])


counts = Counter(sublistSort)

for s,num in counts.items():
    if num > 1: # ignore unique names 
        # get last element of sorted sub list
        number = sublistSort[-1]
        # split name and number elements
        number_split = mysplit(number)
        # increment number
        number_inc = number_split[1] + 1 
        # form new element name
        new_number = number_split[0] + number_inc
        # append new element name to original list
        mylist.append(new_number)


print('#########')
print(mylist)
编辑:所以这个工作,我只需要现在包装成一个函数。如果有人想到使用花式排序方法等的更好的方法仍然感兴趣,。

mylist = ["point1", "feature1", "point2", "area1", "point3", "feature2", "area2"]

def mysplit(s):
     head = s.rstrip('0123456789')
     tail = s[len(head):]
     return head, tail

# extract items starting with specified string into separate sub list
sublist = [x for x in mylist if x.startswith('point')]
# sort sub list alpha-numerically
sublistSort = sorted(sublist, key=lambda item: (int(item.partition(' ')[0])
                               if item[0].isdigit() else float('inf'), item))
print(sublistSort[-1])

number = sublistSort[-1]
number_split = mysplit(number)
number_inc = str(int(number_split[1]) + 1)
new_number = number_split[0] + number_inc
mylist.append(new_number)

print('#########')
print(mylist)

3 个答案:

答案 0 :(得分:1)

一般解决方案是这样的:

def get_index(mylist, new_element):
    index = 1
    for p in mylist:
        if p[:len(new_element)] == new_element:
            index = p[len(new_element):]
    return int(index) + 1

mylist = ["point1", "feature1", "point2", "area1", "point3", "feature2", "area2"]
new_element = 'point'
mylist.append(new_element + str(get_index(mylist, new_element)))

print mylist

或者只是:

def add_new_element(mylist, new_element):
    index = 1
    for p in mylist:
        if p[:len(new_element)] == new_element:
            index = p[len(new_element):]
    mylist.append(new_element + str(int(index) + 1))

<强>输出

['point1', 'feature1', 'point2', 'area1', 'point3', 'feature2', 'area2', 'point4']

这个想法是:

  • 搜索列表中的元素
  • 如果元素退出然后取数字,我将其命名为index
  • return index + 1
  • 然后您可以将其附加到您的列表

答案 1 :(得分:1)

您可以使用lambda表达式过滤列表,使其仅包含与新元素相同类型的元素。然后,您可以使用此列表的长度来查找新索引并相应地附加新项目:

mylist = ["point1", "feature1", "point2", "area1", "point3", "feature2", "area2"]

def append_item(new_item):
    entries_list = filter(lambda x: new_item in x, mylist)
    new_entry = new_item + (len(entries_list) + 1).__str__() 
    mylist.append(new_entry)

append_item("area")

答案 2 :(得分:0)

这是一个不同的方法,如果你想要你可以使用:

mylist = ["point1", "feature1", "point2", "area1", "point3", "feature2", "area2"]

from collections import defaultdict
import itertools
d=defaultdict(list)
for i in mylist:
    d[i[:-1]].append(i)

def no_dublicate(append_items):
    for i in append_items:
        for k, m in d.items():
            if i == k:
                d[k].append(i + str(len(m) + 1))

    return sum(d.values(),[])


print(no_dublicate(['area','area','area','feature','feature','point','feature']))

输出:

['point1', 'point2', 'point3', 'point4', 'feature1', 'feature2', 'feature3', 'feature4', 'feature5', 'area1', 'area2', 'area3', 'area4', 'area5']