简体   繁体   English

Python元组字符串列表

[英]Python List of Strings to Tuple Pairs

I am having some difficulty coming up with an efficient way of taking a list of strings and converting it to tuple pairs. 我遇到一些困难,想出一种有效的方法来获取字符串列表并将其转换为元组对。 I have a list similar to: 我有一个类似于的列表:

listOfNames = ['red-l','blue-l','green-s','red-s','blue-s']

Every color in this example (red, blue, and green) has either a '-l' or '-s' entry or both. 此示例中的每种颜色(红色,蓝色和绿色)都有“-l”或“-s”条目或两者都有。 I need to convert this list of strings into tuple pairs such as: 我需要将这个字符串列表转换为元组对,例如:

tupleOfNames = [('red-l','red-s'),(None,'green-s'),('blue-l','blue-s')]

I think regular expressions is needed but I am not sure how to do so. 我认为需要正则表达式,但我不知道该怎么做。 Any help is greatly appreciated. 任何帮助是极大的赞赏。 Thanks 谢谢

A possible solution, We can sort the list firstly and then groupby the color part of each term and transform each group into a tuple, if it contains only one element insert a None in the tuple: 一个可能的解决方案,我们可以先对列表进行排序,然后按每个术语的颜色部分进行分组,并将每个组转换为元组,如果它只包含一个元素,则在元组中插入一个None:

import re
from itertools import groupby

li = []
listOfNames.sort()
for k, g in groupby(listOfNames, lambda s: re.findall("(.*)-", s)):
    liG = list(g)
    if len(liG) == 1:
        li.append((None, liG[0]))
    else:
        li.append(tuple(liG))

li
# [('blue-l', 'blue-s'), (None, 'green-s'), ('red-l', 'red-s')]

I wrote this function which is far from perfect, but delivers the result you wish for: 我写了这个功能远非完美,但提供了你想要的结果:

  def tupleofnames(listofnames):
        result = []
        colors = set([x[:-2] for x in listOfNames])    
        for c in colors:         
            if c+"-l" in listofnames:
                if c+'-s' in listofnames:
                    result.append((c+"-l",c+'-s'))
                else: 
                    result.append((c+"-l",None))
            else:
                result.append((None,c+"-s"))
        return result

Result looks like: 结果如下:

[(None, 'green-s'), ('red-l', 'red-s'), ('blue-l', 'blue-s')]
listOfNames = ['red-l','blue-l','green-s','red-s','blue-s']
l_list = [a[:-2] for a in filter(lambda x:x[-1]=='l',listOfNames)]
s_list = [a[:-2] for a in filter(lambda x:x[-1]=='s',listOfNames)]
s = {a[:-2] for a in listOfNames}
tuplesOfNames = [tuple([c+'-l' if c in l_list else None,c+'-s' if c in s_list else None]) for c in s]

Output: 输出:

[('blue-l', 'blue-s'), ('red-l', 'red-s'), (None, 'green-s')]

This will be slightly faster than alternatives due to spliting into 2 separate lists for elements, so that lookup is bit faster. 由于分成2个单独的元素列表,因此这将比其他选项略快,因此查找速度更快。

I think a nice (and perhaps better) solution is: 我认为一个不错的(也许是更好的)解决方案是:

from collections import defaultdict
d = defaultdict(list)
listOfNames = ['red-l','blue-l','green-s','red-s','blue-s']
# Go over the list and remember for each color the entry 
for s in listOfNames:
   d[s[:-2]].append(s[-1])
# Go over the colors and produce the appropriate tuple
[ (key+'-l' if 'l' in d[key] else None, key+'-s' if 's' in d[key] else None) for key in d.keys() ]

That outputs: 那输出:

[('blue-l', 'blue-s'), ('red-l', 'red-s'), (None, 'green-s')]

With that method you go just one time over the original list and one time over the color keys (which is smaller). 使用该方法,您只需在原始列表上进行一次,在颜色键上进行一次(较小)。

The access to the dictionary is O(1) on average so thats should work fast enough. 对字典的访问平均为O(1) ,因此应该足够快。

Check out the itertools.product() function. 查看itertools.product()函数。 This returns the cartesian product of two lists. 这将返回两个列表的笛卡尔积。 In your case you could do, 在你的情况下,你可以做到,

from itertools import product

l_names = ['red-l', 'blue-l']
s_names = ['red-s', 'blue-s', 'green-s']

tupleOfNames = list(product(l_names, s_names))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM