【问题标题】:Evaluating into two or more lists评估成两个或多个列表
【发布时间】:2009-09-28 11:24:59
【问题描述】:

你们好,codeboys 和 codegirls!

我遇到了一个看似简单的解决方案的简单问题。但作为一名 Python 新手,我觉得在某个地方有更好的方法。

假设您有一个混合字符串列表。麻袋中有两种基本类型的字符串 - 一种带有“=”(a=potato)和一种没有(Lady Jane)。您需要将它们分类为两个列表。

显而易见的方法是:

for arg in arguments:
   if '=' in arg:
       equal.append(arg)
   else:
       plain.append(arg)

还有其他更优雅的方法吗?比如:

equal = [arg for arg in arguments if '=' in arg]

但是要排序到多个列表中?

如果您有不止一种类型的数据怎么办?

【问题讨论】:

  • 我认为您的明显方法非常好,并且比迄今为止建议的许多答案更具可读性!
  • 确实,我发现列表推导是 python 最优雅的特性之一,我在编写 C++ 时一直渴望它!其中 2 个比任何一个答案都好

标签: python list


【解决方案1】:

试试

for arg in arguments:
    lst = equal if '=' in arg else plain
    lst.append(arg)

或者(丑陋的)

for arg in arguments:
    (equal if '=' in arg else plain).append(arg)

第三种选择:创建一个提供append() 的类,并将其分类为多个列表。

【讨论】:

  • 我发现list = ('=' in arg) and equal or plain这个表格更易读。
  • 我认为“a if cond else b”是非常易读的英文;我只是不喜欢在一行中写太多。
  • 应该是else plain
  • @giorgian,你有一个真正的 可怕 想法:当equal 为空时(即在开始时)你的“更易读”的表格总是给出plain ,因此不会将任何内容附加到 equal ——“更具可读性”(eek!-)。
【解决方案2】:

您可以为此使用itertools.groupby()

import itertools
f = lambda x: '=' in x
groups = itertools.groupby(sorted(data, key=f), key=f)
for k, g in groups:
    print k, list(g)

【讨论】:

  • 我以为他要的是优雅
  • 排序使其成为 nlog(n),而存在更简单的 O(n) 解决方案。
【解决方案3】:

我会选择两个列表推导。虽然这确实会产生一些开销(列表上有两个循环),但使用列表推导式比使用 for 更符合 Pythonic。它也(在我看来)比使用各种非常酷的技巧更具可读性,但很少有人知道。

【讨论】:

    【解决方案4】:
    def which_list(s):
        if "=" in s: 
            return 1
        return 0
    
    lists = [[], []]
    
    for arg in arguments:
        lists[which_list(arg)].append(arg)
    
    plain, equal = lists
    

    如果您有更多类型的数据,请在which_list 中添加一个 if 子句,并将lists 初始化为更多空列表。

    【讨论】:

    • which_list 可以简单得多 - 请参阅我的答案。否则,我们的答案非常接近。
    • 确实可以,但是OP询问了两种以上可能性的情况,我想在初始设计中处理。
    • 在这种情况下,我认为列表字典会更清晰。列表索引毫无意义。
    • 是的,列表的字典更好!
    【解决方案5】:

    我会选择 Edan 的方法,例如

    equal = [arg for arg in arguments if '=' in arg]
    plain = [arg for arg in arguments if '=' not in arg]
    

    【讨论】:

      【解决方案6】:

      我在这里某处读到,您可能对以下解决方案感兴趣 将适用于更多两个标识符(等号和空格)。

      以下解决方案只需要您更新 uniques 设置为 您想匹配的任何内容,结果都会放在列表字典中 以标识符为键。

      uniques = set('= ')
      matches = dict((key, []) for key in uniques)
      
      for arg in args:
          key = set(arg) & uniques
          try:
              matches[key.pop()].append(arg)
          except KeyError:
              # code to handle where arg does not contain = or ' '.
      

      现在上面的代码假设您的标识符只有一个匹配项 在你的arg。即你没有一个看起来像'John= equalspace'arg。 您还必须考虑如何处理与集合中的任何内容都不匹配的案例(出现KeyError。)

      【讨论】:

        【解决方案7】:

        另一种方法是使用filter 函数,尽管它不是最有效的解决方案。
        示例:

        >>> l = ['a=s','aa','bb','=', 'a+b']
        >>> l2 = filter(lambda s: '=' in s, l)
        >>> l3 = filter(lambda s: '+' in s, l)
        >>> l2
        ['a=s', '=']
        >>> l3
        ['a+b']
        

        【讨论】:

          【解决方案8】:

          我把这些放在一起,然后看到 Ned Batchelder 已经采取了同样的策略。不过,我选择打包拆分方法而不是列表选择器,并且只对 False 和 True 使用隐含的 0/1 值。

          def split_on_condition(source, condition):
              ret = [],[]
              for s in source:
                  ret[condition(s)].append(s)
              return ret
          
          src = "z=1;q=2;lady jane;y=a;lucy in the sky".split(';')
          
          plain,equal = split_on_condition(src, lambda s:'=' in s)
          

          【讨论】:

            【解决方案9】:

            你的方法是最好的。对于仅分类为两个列表的情况,再清​​楚不过了。如果您希望它是单行的,请将其封装在一个函数中:

            def classify(arguments):
                equal, plain = [], []
                for arg in arguments:
                    if '=' in arg:
                        equal.append(arg)
                    else:
                        plain.append(arg)
                return equal, plain
            
            
            equal, plain = classify(lst)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-06-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-11
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多