Equivalent of R's paste command for vector of numbers in Python

前端 未结 5 947
栀梦
栀梦 2020-12-16 14:52

This must have been asked before, but I\'m afraid I can\'t find the answer.

In R, I can write

paste0(\'s\', 1:10)

which returns a l

相关标签:
5条回答
  • 2020-12-16 15:02

    None of these answers generalizes to arbitrary numbers of arguments like paste in R does. Here is a fairly faithful port of the original R function. The only thing to remember is that each element must be presented as a list, since character strings in R are actually just vectors of characters under the hood:

    import itertools
    
    def paste(*args, sep = ' ', collapse = None):
        """
        Port of paste from R
        Args:
            *args: lists to be combined
            sep: a string to separate the terms
            collapse: an optional string to separate the results
        Returns:
            A list of combined results or a string of combined results if collapse is not None
        """
        combs = list(itertools.product(*args))
        out = [sep.join(str(j) for j in i) for i in combs]
        if collapse is not None:
            out = collapse.join(out)
        return out
    

    Usage:

    paste (['s'], range(10), sep = '')
    Out[62]: ['s0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9']
    paste (['s'], range(2), ['t'], range(3), sep = '')
    Out[63]: ['s0t0', 's0t1', 's0t2', 's1t0', 's1t1', 's1t2']
    paste (['s'], range(2), ['t'], range(3), sep = '', collapse = ':')
    Out[64]: 's0t0:s0t1:s0t2:s1t0:s1t1:s1t2'
    

    You can get paste0 by using currying:

    from functools import partial
    
    paste0 = partial(paste, sep = '')
    
    0 讨论(0)
  • 2020-12-16 15:02

    This is a bit closer to R's paste (including it's quirk of recycling arguments with length other than 1:

    def paste(*args, sep = " ", collapse = None):
        l = [list(arg) if isinstance(arg, str) else arg if hasattr(arg, '__len__') else list(str(arg)) for arg in args]
        l = list(itertools.islice((sep.join(parts) for parts in zip(*(itertools.cycle(map(str, e)) for e in l))), (max((len(x) for x in l)))))
        if collapse is not None:
            l = collapse.join(l)
        return l
    
    paste(["a", "b"], range(2), "!")
    # ['a 0 !', 'b 1 !']
    
    0 讨论(0)
  • 2020-12-16 15:10
    >>> ["s" + str(i) for i in xrange(1,11)]
    ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10']
    

    EDIT: range works in both Python 2 and Python 3, but in Python 2 xrange is a little more efficient potentially (it's a generator not a list). Thansk @ytu

    0 讨论(0)
  • 2020-12-16 15:16

    The answer by cdyson37 is the most pythonic one; of course you can still use range rather than xrange in your case.

    In Python2, you can also put more emphasis on functional style with something like:

    map(lambda x: "s"+str(x), range(1,11))
    
    0 讨论(0)
  • 2020-12-16 15:21
    >>> list(map('s{}'.format, range(1, 11)))
    ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10']
    
    0 讨论(0)
提交回复
热议问题