在Python中为ID分配字符串

时间:2013-09-04 04:38:18

标签: python string

我正在使用python读取文本文件,格式化每列中的值可能是数字或字符串。

当这些值是字符串时,我需要分配该字符串的唯一ID(在同一列下的所有字符串中都是唯一的;如果相同的字符串出现在同一列的其他位置,则必须分配相同的ID)。

什么是有效的方法呢?

3 个答案:

答案 0 :(得分:12)

使用defaultdict和默认值factory生成新ID:

ids = collections.defaultdict(itertools.count().next)
ids['a']  # 0
ids['b']  # 1
ids['a']  # 0

当您在defaultdict中查找某个键时,如果它尚未存在,则defaultdict会调用用户提供的默认值factory来获取该值并在返回之前将其存储。

collections.count()创建一个从0开始计数的迭代器,因此collections.count().next是一个绑定方法,只要你调用它就会产生一个新的整数。

结合起来,这些工具产生一个dict,当你查找以前从未查找过的东西时,它会返回一个新的整数。

答案 1 :(得分:2)

对于python 3更新了defaultdict answer,其中.next现在为.__next__,对于pylint合规性,不鼓励使用“magic”__*__方法:

ids = collections.defaultdict(functoools.partial(next, itertools.count()))

答案 2 :(得分:0)

创建一个集合,然后将字符串添加到集合中。这将确保字符串不重复;然后你可以使用enumerate来获取每个字符串的唯一id。在再次写出文件时使用此ID。

这里我假设第二列是您要扫描文本或整数的列。

seen = set()
with open('somefile.txt') as f:
   reader = csv.reader(f, delimiter=',')
   for row in reader:
      try:
         int(row[1])
      except ValueError:
         seen.add(row[1]) # adds string to set

# print the unique ids for each string

for id,text in enumerate(seen):
    print("{}: {}".format(id, text))

现在您可以采用相同的逻辑,并在文件的每一列中复制它。如果您知道高级列长度,则可以拥有集合列表。假设文件有三列:

unique_strings = [set(), set(), set()]

with open('file.txt') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader:
       for column,value in enumerate(row):
           try:
               int(value)
           except ValueError:
               # It is not an integer, so it must be
               # a string
               unique_strings[column].add(value)