【问题标题】:Splitting List That Contains Strings and IntegersPython - 包含字符串和整数的拆分列表
【发布时间】:2013-01-24 11:30:06
【问题描述】:
myList = [ 4,'a', 'b', 'c', 1 'd', 3]

如何将这个列表分成两个列表,一个包含字符串,另一个包含 elegant/pythonic 方式的整数?

输出:

myStrList = [ 'a', 'b', 'c', 'd' ]

myIntList = [ 4, 1, 3 ]

注意:没有实现这样的列表,只是考虑如何为这样的问题找到一个优雅的答案(有吗?)。

【问题讨论】:

  • 我认为你需要一个正则表达式
  • 恕我直言,这是非常丑陋的解决方案。我宁愿遍历列表并拆分。
  • 检查类型一开始就不是pythonic,创建这样一个混合类型列表也是如此。也许您应该了解根据输入的目的拆分数据,而不是稍后再修改它?
  • @bozdoz -- 如果您尝试将一个整数传递给正则表达式,它会阻塞(不是吗?)
  • 投票结束,因为您要求一个优雅的解决方案来解决您实际上并没有遇到的问题,并且没有人编写优雅的代码会遇到。 (也因为你没有回答隐含的“你试过什么?”)

标签: python string list int


【解决方案1】:

正如其他人在 cmets 中提到的那样,您应该真正开始考虑如何首先摆脱包含非同质数据的列表。但是,如果这真的 不能 完成,我会使用 defaultdict:

from collections import defaultdict
d = defaultdict(list)
for x in myList:
   d[type(x)].append(x)

print d[int]
print d[str]

【讨论】:

    【解决方案2】:

    您可以使用列表推导:-

    >>> myList = [ 4,'a', 'b', 'c', 1, 'd', 3]
    >>> myIntList = [x for x in myList if isinstance(x, int)]
    >>> myIntList
    [4, 1, 3]
    >>> myStrList = [x for x in myList if isinstance(x, str)]
    >>> myStrList
    ['a', 'b', 'c', 'd']
    

    【讨论】:

    • 如果类型是提前知道的并且没有太多的话,这很有效:)
    • 如果列表中的数字是浮点值,则使用dtype 作为float 而不是int。否则,myIntList 将返回一个空列表。
    【解决方案3】:
    def filter_by_type(list_to_test, type_of):
        return [n for n in list_to_test if isinstance(n, type_of)]
    
    myList = [ 4,'a', 'b', 'c', 1, 'd', 3]
    nums = filter_by_type(myList,int)
    strs = filter_by_type(myList,str)
    print nums, strs
    
    >>>[4, 1, 3] ['a', 'b', 'c', 'd']
    

    【讨论】:

      【解决方案4】:

      根据在原始列表中找到的类型拆分列表

      myList = [ 4,'a', 'b', 'c', 1, 'd', 3]
      types = set([type(item) for item in myList])
      ret = {}
      for typeT in set(types):
          ret[typeT] = [item for item in myList if type(item) == typeT]
      
      >>> ret
      {<type 'str'>: ['a', 'b', 'c', 'd'], <type 'int'>: [4, 1, 3]}
      

      【讨论】:

        【解决方案5】:

        我将通过回答一个 Python 常见问题来总结这个线程:“你如何编写一个以任意顺序接受参数的方法,类型范围很窄?”

        假设所有参数的从左到右的顺序并不重要,试试这个(基于@mgilson 的回答):

        def partition_by_type(args, *types):
            d = defaultdict(list)
        
            for x in args:
                d[type(x)].append(x)
        
            return [ d[t] for t in types ]
        
        def cook(*args):
            commands, ranges = partition_by_type(args, str, range)
        
            for range in ranges:
                for command in commands:
                    blah blah blah...
        

        现在您可以致电cook('string', 'string', range(..), range(..), range(..))。参数顺序在其类型内是稳定的。

        # TODO  make the strings collect the ranges, preserving order
        

        【讨论】:

          【解决方案6】:
          import strings;
          num=strings.digits;
          str=strings.letters;
          num_list=list()
          str_list=list()
          for i in myList:
              if i in num:
                  num_list.append(int(i))
              else:
                  str_list.append(i)
          

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
          【解决方案7】:

          您可以使用此代码作为示例,通过使用函数 isdigit() 创建两个不同的列表,该函数检查字符串中的整数。

          ip=['a',1,2,3]
          m=[]
          n=[]
          for x in range(0,len(ip):
              if str(ip[x]).isdigit():
                  m.append(ip[x])
              else:n.append(ip[x])
          print(m,n)
          

          【讨论】:

          • 此答案不正确,包含错误。不正确,因为使用 isdigit() 您检查元素是否是仅包含数字但不将数字与字符串分开的字符串(因为您可以将其应用于字符串)。例如列表['a','b',1,2,3,'10'] 将返回[2, 3, 4, 5] ['a', 'b'] 而不是[1,2,3]['a','b','10']。这让我想到了错误:在附加到m 时,您应该附加ip[x]。备注,最好使用len(ip)而不是硬编码长度。
          • 我现在注意到了这个错误,因为我使用 isdigit 返回列表中数字的位置。谢谢
          • 你还是分不清10'10'
          • 这是因为我将整个列表转换为字符串以便使用 isdigit 这就是为什么它不会区分它们。 :)
          • 是的,我知道,所以你同意你没有回答 OP 的问题?
          【解决方案8】:
          n = (input("Enter  string and digits: "))
          d=[]
          s=[]
          for  x in range(0,len(n)):
              if str(n[x]).isdigit():
                  d.append(n[x])
              else
                  s.append(n[x])
          print(d)
          print(s)
          

          编辑 1:这是另一个解决方案

          import re
          x = input("Enter any string that contains characters and integers: ")
          s = re.findall('[0-9]',x)
          print(s)
          c = re.findall('[a-z/A-Z]',x)
          print(c)
          

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-11-04
          • 2013-08-04
          • 1970-01-01
          • 2020-02-20
          • 2013-03-30
          • 1970-01-01
          • 2023-03-31
          相关资源
          最近更新 更多