Python 中数字向量的 R 粘贴命令的等价物

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

这个肯定有人问过,但恐怕找不到答案了。

在R中,我可以写

paste0('s', 1:10)

其中 returns 10 个字符(字符串)变量的列表:

[1] "s1"  "s2"  "s3"  "s4"  "s5"  "s6"  "s7"  "s8"  "s9"  "s10"

如何在 Python 中简单地执行此操作?我能想到的唯一方法是用for循环,但必须有一个简单的一行。

我试过

's' + str(np.arange(10))
['s', str(np.arange(10))]
>>> ["s" + str(i) for i in xrange(1,11)]
['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10']

编辑:range 在 Python 2 和 Python 3 中都有效,但在 Python 2 中 xrange 可能更有效(它是生成器而不是列表)。谢谢@ytu

cdyson37的回答是最pythonic的;当然,您仍然可以使用 range 而不是 xrange

在 Python2 中,您还可以更加强调函数式样式,例如:

map(lambda x: "s"+str(x), range(1,11))
>>> list(map('s{}'.format, range(1, 11)))
['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10']

None 这些答案可以概括为任意数量的参数,就像 R 中的 paste 一样。这是原始 R 函数的相当忠实的端口。唯一要记住的是,每个元素都必须以列表形式呈现,因为 R 中的字符串实际上只是引擎盖下的字符向量:

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

用法:

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'

你可以通过柯里化获得paste0

from functools import partial

paste0 = partial(paste, sep = '')

这有点接近 R 的粘贴(包括它回收长度不是 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 !']