假设我将以下伪代码转换为Python。关于具体表示为1st half of A
的参数,Python是否有像A[1..n/2]
这样的机制(我不时看到的另一种伪代码快捷方式)不需要复制来传递部分列表作为参数?
Count(array A, length n)
if n = 1 return 0
else
x = Count(1st half of A, n/2)
y = Count(2nd half of A, n/2)
return x + y
如果没有这样的机制,我会根据需要传递索引。
答案 0 :(得分:3)
答案是否定的。您必须传递索引(或slice
个对象)。
您还可以编写一个list
子类,通过将“视图”返回到原始列表而不是副本来处理切片。我实际上已经解决了几次,并且发现完全正确是很棘手的,但是由于您的应用程序不需要负索引,切片分配或跳过参数,所以它变得更加容易。这是一个快速尝试:
class ListWithAView(list):
class ListView(object):
def __init__(self, list, start, stop, step):
self.list = list
self.start = start
self.stop = stop
self.step = step
def __iter__(self):
for i in xrange(self.start, self.stop, self.step):
yield self.list[i]
def __len__(self):
return (self.stop - self.start) / self.step
def __getitem__(self, i):
if isinstance(i, slice):
return type(self)(self.list, (i.start or 0) + self.start,
min(self.start + (i.stop or 0), self.stop),
i.step * self.step if i.step else self.step)
if isinstance(i, int) and i < len(self):
return self.list[i+self.start]
raise IndexError("invalid index: %r" % i)
def __setitem__(self, i, v):
if isinstance(i, int):
self.list[i+self.start] = v
else:
raise IndexError("invalid index: %r" % i)
def __repr__(self):
return "<slice [%s:%s:%s] of list id 0x%08x>: %s" % (self.start, self.stop, self.step, id(self.list), self)
def __str__(self):
return str(list(self))
__str__ = __repr__
@property
def view(self):
return self.ListView(self, 0, len(self), 1)
此列表子类的view
属性返回一个ListView
对象,其行为与列表非常相似,但是获取并设置基础列表中的数据,而不是存储任何项本身。返回的对象最初引用整个列表,但如果需要可以进一步切片。为简单起见,不处理否定步骤,您不能进行切片分配,只需单个项目。
快速演示:
seq = ListViwthAView(range(100))
view = seq.view[10:20][5:7]
view[0] = 1337
print seq[15] # 1337
答案 1 :(得分:2)
您可以在此处使用slice
个对象,但遗憾的是,没有__len__
方法,因此您必须使用(s.start + s.stop)/2
来计算长度。任何时候你明智地“实现”子阵列(当然创建副本),你可以使用A[s]
def count(A, s=None):
if s is None:
s=slice(0, len(A))
if s.start + 1 == s.stop:
return 1
else:
x = count(A, slice(s.start, (s.start + s.stop)/2))
y = count(A, slice((s.start + s.stop)/2, s.stop))
return x + y
print count([1,2,3,4,5])
答案 2 :(得分:2)
在您的示例中,最佳解决方案是按照您的建议传递列表和索引。
如果您不需要索引切片(例如,如果仅在列表的前半部分和后半部分上使用迭代器就足够了),则可以使用islice
函数来自{{ 1}}。 E.g。
itertools