在python中,有没有一种很好的方法可以遍历多个列表(有时它们是单值的)

在python中,有没有一种很好的方法可以遍历多个列表(有时它们是单值的),python,numpy,Python,Numpy,所以我的问题基本上和“zip”(或izip)有关,这个问题以前被问过 如果我有两个变量——它们要么是长度为n的值的1d数组,要么是单个值,那么我如何循环遍历它们以获得返回的n个值 “zip”有点像我想要的——除了当我传入一个值和它抱怨的数组时 下面我有一个例子来说明我的目标——基本上我有一个c函数,它比python的计算效率更高。我希望它能像一些numpy函数一样处理数组和标量的混合,所以我为它写了一个python包装器。然而,就像我说的“zip”失败了。我想原则上我可以对输入进行一些测试,并

所以我的问题基本上和“zip”(或izip)有关,这个问题以前被问过

如果我有两个变量——它们要么是长度为n的值的1d数组,要么是单个值,那么我如何循环遍历它们以获得返回的n个值

“zip”有点像我想要的——除了当我传入一个值和它抱怨的数组时

下面我有一个例子来说明我的目标——基本上我有一个c函数,它比python的计算效率更高。我希望它能像一些numpy函数一样处理数组和标量的混合,所以我为它写了一个python包装器。然而,就像我说的“zip”失败了。我想原则上我可以对输入进行一些测试,并为标量和数组的每个变体编写不同的语句——但python似乎应该有更聪明的东西……)有什么建议吗

"""
    Example of zip problems.
"""

import numpy as np
import time

def cfun(a, b) :
    """
        Pretending to be c function which doesn't deal with arrays
    """
    if not np.isscalar(a)   or  not np.isscalar(b)  :

        raise Exception('c is freaking out')
    else :

        return a+b

def pyfun(a, b) :
    """
        Python Wrappper - to deal with arrays input
    """

    if not np.isscalar(a)   or  not np.isscalar(b) :
        return np.array([cfun(a_i,b_i) for a_i, b_i in zip(a,b)])

    else :

        return cfun(a, b)

    return cfun(a,b)


a = np.array([1,2])
b= np.array([1,2])
print pyfun(a, b)

a = [1,2]
b = 1
print pyfun(a, b)
编辑:


非常感谢大家的建议。我想我必须选择np.braodcast来解决这个问题——因为从我的角度来看,它似乎是最简单的….

一个装饰程序,它可以选择将每个参数转换为序列。以下是普通python(非numpy)版本:

因此,在您的示例中,我们需要使用
not np.isscalar
作为谓词,使用
np.array
作为修饰符。由于使用了decorator,
pyfun
始终接收一个数组

#UNTESTED
def listify(f):
  def dolistify(*args):
    from collections import Iterable
    return f(*(np.array([a]) if np.isscalar(a) else a for a in args))
  return dolistify

@listify
def pyfun(a, b) :
    """
        Python Wrappper - to deal with arrays input
    """

    return np.array([cfun(a_i,b_i) for a_i, b_i in zip(a,b)])
或者你也可以将同样的想法应用到
zip

#UNTESTED
def MyZip(*args):
  return zip(np.array([a]) if np.isscalar(a) else a for a in args)

def pyfun(a, b) :
    """
        Python Wrappper - to deal with arrays input
    """

    return np.array([cfun(a_i,b_i) for a_i, b_i in MyZip(a,b)])

如果要强制广播,可以使用
numpy.lib.stride\u tricks.broadcast\u数组
。重复使用您的
cfun

def pyfun(a, b) :
    if not (np.isscalar(a) and np.isscalar(b)) :
        a_bcast, b_bcast = np.lib.stride_tricks.broadcast_arrays(a, b)
        return np.array([cfun(j, k) for j, k in zip(a_bcast, b_bcast)])
    return cfun(a, b)
现在:

>>> pyfun(5, 6)
11
>>> pyfun(5, [6, 7, 8])
array([11, 12, 13])
>>> pyfun([3, 4, 5], [6, 7, 8])
array([ 9, 11, 13])

对于您的特定应用程序,可能没有Rob纯python的优势,因为您的函数仍在python循环中运行。

由于您使用numpy,因此不需要使用
zip()
来迭代多个数组和标量。您可以使用
numpy.broadcast()


我将您的
'
更改为
”,所以so的渲染器会喜欢它。顺便说一句,
实际上比
'
更适合描述文档字符串。上面说<代码>为保持一致性,请始终在docstring周围使用“三重双引号”。如果在docstring中使用任何反斜杠,请使用r“”“原始三重双引号”。对于Unicode文档字符串,请使用u”““Unicode三引号字符串”“”@MarkHildreth--PEP 257。我知道它在某个地方的政治公众人物中,但当我在政治公众人物8中找不到它时,我开始怀疑我是不是在编造它。我是在我以前使用的发电机经过
numpy
升级后不再工作后遇到这个问题的。这确实很有用,但问题的表述和标题似乎掩盖了找到答案的过程。
>>> pyfun(5, 6)
11
>>> pyfun(5, [6, 7, 8])
array([11, 12, 13])
>>> pyfun([3, 4, 5], [6, 7, 8])
array([ 9, 11, 13])
In [5]:

list(np.broadcast([1,2,3], 10))

Out[5]:

[(1, 10), (2, 10), (3, 10)]

In [6]:

list(np.broadcast([1,2,3], [10, 20, 30]))

Out[6]:

[(1, 10), (2, 20), (3, 30)]

In [8]:

list(np.broadcast([1,2,3], 100, [10, 20, 30]))

Out[8]:

[(1, 100, 10), (2, 100, 20), (3, 100, 30)]