代码之家  ›  专栏  ›  技术社区  ›  Tall Jeff

我如何做strtok()在C语言中,在Python中所做的事情?

  •  8
  • Tall Jeff  · 技术社区  · 16 年前

    我正在学习Python,并试图找出一种有效的方法,将由逗号分隔的数字串标记为一个列表。格式良好的案例正如我所预期的那样有效,但格式不太好的案例就没有那么多了。

    如果我有这个:

    A = '1,2,3,4'
    B = [int(x) for x in A.split(',')]
    
    B results in [1, 2, 3, 4]
    

    这就是我所期望的,但是如果字符串更像

    A = '1,,2,3,4,'
    

    如果我对B使用与上面相同的列表理解表达式,我会得到一个异常。我想我理解为什么(因为一些“x”字符串值不是整数),但我认为有一种方法可以非常优雅地解析它,这样字符串a的标记化工作起来就更直接一些 strtok(A,“,\n\t”) 在C中迭代调用时会执行。

    明确我的要求;我正在寻找Python中一种优雅/高效/典型的方式,以获得以下所有字符串示例:

    A='1,,2,3,\n,4,\n'
    A='1,2,3,4'
    A=',1,2,3,4,\t\n'
    A='\n\t,1,2,3,,4\n'
    

    返回与以下内容相同的列表:

    B=[1,2,3,4]
    

    通过某种紧凑的表达。

    9 回复  |  直到 15 年前
        1
  •  29
  •   Dave Ray    16 年前

    这个怎么样:

    A = '1, 2,,3,4  '
    B = [int(x) for x in A.split(',') if x.strip()]
    

    x、 strip()修剪字符串中的空白,如果字符串全部为空白,则将使其为空。在布尔上下文中,空字符串是“false”,因此它由列表的if部分过滤。

        2
  •  4
  •   Nick    16 年前

    一般来说,我尽量避免使用正则表达式,但是如果你想在一堆不同的事情上进行分割,它们是有效的。试试这个:

    import re
    result = [int(x) for x in filter(None, re.split('[,\n,\t]', A))]
    
        3
  •  4
  •   Alec Thomas    16 年前

    嗯,函数的优点(加上一点生成器表达式):

    a = "1,2,,3,4,"
    print map(int, filter(None, (i.strip() for i in a.split(','))))
    

    要获得全功能的乐趣:

    import string
    a = "1,2,,3,4,"
    print map(int, filter(None, map(string.strip, a.split(','))))
    
        4
  •  3
  •   user1683793    8 年前

    为了完整起见,我将回答这个七年前的问题: 使用strtok的C程序:

    int main()
    {
        char myLine[]="This is;a-line,with pieces";
        char *p;
        for(p=strtok(myLine, " ;-,"); p != NULL; p=strtok(NULL, " ;-,"))
        {
            printf("piece=%s\n", p);
        }
    }
    

    import re
    myLine="This is;a-line,with pieces"
    for p in re.split("[ ;\-,]",myLine):
        print("piece="+p)
    
        5
  •  1
  •   runeh    16 年前

    如果所有的数字都是整数,这将起作用,并且不会引发异常。这个 isdigit() 如果字符串中有小数点,则调用为false。

    >>> nums = ['1,,2,3,\n,4\n', '1,2,3,4', ',1,2,3,4,\t\n', '\n\t,1,2,3,,4\n']
    >>> for n in nums:
    ...     [ int(i.strip()) for i in n if i.strip() and i.strip().isdigit() ]
    ... 
    [1, 2, 3, 4]
    [1, 2, 3, 4]
    [1, 2, 3, 4]
    [1, 2, 3, 4]
    
        6
  •  1
  •   Algorias    16 年前

    这个怎么样?

    >>> a = "1,2,,3,4,"
    >>> map(int,filter(None,a.split(",")))
    [1, 2, 3, 4]
    

    过滤器将删除所有假值(即空字符串),然后将其映射到int。

        7
  •  1
  •   joeforker    16 年前

    为什么要接受不能给你的口译员带来麻烦的劣质替代品?使用ctypes,您可以直接调用真实的内容!:-)

    # strtok in Python
    from ctypes import c_char_p, cdll
    
    try: libc = cdll.LoadLibrary('libc.so.6')
    except WindowsError:
         libc = cdll.LoadLibrary('msvcrt.dll')
    
    libc.strtok.restype = c_char_p
    dat = c_char_p("1,,2,3,4")
    sep = c_char_p(",\n\t")
    result = [libc.strtok(dat, sep)] + list(iter(lambda: libc.strtok(None, sep), None))
    print(result)
    
        8
  •  0
  •   Josh Smeaton    16 年前

    为什么不干脆用一个try-except块来捕获任何不是整数的东西呢?

        9
  •  0
  •   Aneesh K Thampi    4 年前

    我非常需要Python中的strtok等价物。所以我自己开发了一个简单的

    def strtok(val,delim):
        token_list=[]
        token_list.append(val)  
        for key in delim:       
            nList=[]        
            for token in token_list:            
                subTokens = [ x for x in token.split(key) if x.strip()]
                nList= nList + subTokens            
            token_list = nList  
        return token_list
    
        10
  •  -1
  •   Simon Groenewolt    16 年前

    我想正则表达式就是最好的选择: http://docs.python.org/library/re.html