【问题标题】:Equivalent of R's paste command for vector of numbers in PythonPython中数字向量的R粘贴命令等效
【发布时间】:2015-01-20 13:21:15
【问题描述】:

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

在 R 中,我可以写

paste0('s', 1:10)

返回一个包含 10 个字符(字符串)变量的列表:

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

如何在 Python 中简单地做到这一点?我能想到的唯一方法是使用 for 循环,但必须有一个简单的单行。

我尝试过类似的东西

's' + str(np.arange(10))
['s', str(np.arange(10))]

【问题讨论】:

  • 非常感谢没有同类产品。你认为paste(1:2,1:3)paste("a", character(0)) 的输出是什么?

标签: python r string


【解决方案1】:
>>> ["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

【讨论】:

  • 谢谢!我不确定是否接受这个答案或@jamylak 的。两者对我来说都很好。
  • 在 Python 3 中似乎没有 xrange 函数。 ["s" + str(i) for i in range(1,11)] 工作正常,但 ["s" + str(i) for i in xrange(1,11)] 给出 NameError: name 'xrange' is not defined
  • @cdyson,这种函数中是否有多个+,例如R中的paste0,您可以在其中粘贴您想要的任意多个项目,例如paste0("a",1:10,11:20)?跨度>
  • 您可以使用zip 来完成类似的事情。 ["".join (map (str, x)) for x in zip (["a"]*10, range(1,11), range(11,21))] (Python3) 怎么样。我们必须手动制作 10 个"a"s(zip 不会只是为您重复它们),然后每个 x 变成一个元组,例如("a", 1, 1) 然后我们用map (str, x) 把它们变成一个字符串列表,最后用"".join () 连接它们。
【解决方案2】:
>>> list(map('s{}'.format, range(1, 11)))
['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10']

【讨论】:

  • 我不确定是接受您的回答还是来自@cdyson37 的回答。两个都不错!
  • @jamylak,为什么我得到一个地图对象而不是像你一样在答案中显示结果?我在 spyder 中这样做。
  • @JasonGoal i 现在更新为 list(map(.. 所以 Py3 将成为一个列表
【解决方案3】:

cdyson37 的答案是最 Pythonic 的;当然,在您的情况下,您仍然可以使用range 而不是xrange

在 Python2 中,您还可以通过以下方式更加强调函数式风格:

map(lambda x: "s"+str(x), range(1,11))

【讨论】:

    【解决方案4】:

    这些答案都不能推广到 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 = '')
    

    【讨论】:

    • 如果您使用itertools.product,如果多个参数的长度大于1,您的函数会执行其他操作
    【解决方案5】:

    这有点接近 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 !']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-07
      • 1970-01-01
      • 1970-01-01
      • 2015-02-21
      • 1970-01-01
      相关资源
      最近更新 更多