给定一个列表adjustStyles
,我可以通过执行以下操作来对其进行切片:
a
然而,这只是线性切片。 例如,我想选择2的幂的索引。 不幸的是,这不起作用:
a[start:end:step]
当需要非线性切片时,有没有办法避免循环?
修改: 主要是我需要这个来修改列表。 E.g。
a[slice(2**x for x in range(len(a))]
答案 0 :(得分:2)
您可以使用列表理解:
is_power_of_two = lambda num: num != 0 and ((num & (num - 1)) == 0)
print [item for i, item in enumerate(a) if is_power_of_two(i)]
答案 1 :(得分:1)
我不确定这是否是你想要的,但你可以试试这个:
# Example list
l = [1,2,3,4,5,6,7,8]
result = list(map(lambda y: l[y], list(filter(lambda x: (x>0 and (x & (x-1) == 0)),list(range(0,len(l)))))))
print(result)
结果是:
[2, 3, 5]
但如果我是你,我就不会使用它,因为它几乎不可读。
答案 2 :(得分:1)
为什么要迭代整个列表,只需要2 ** i
个元素。这极大地提高了复杂性。
a = range(100)
def two_power_slice(lst):
result = []
for i in xrange(len(lst)):
j = 2 ** i
if j > len(lst) - 1:
break
result.append(lst[j])
return result
print two_power_slice(a)
我认为你也可以使用对数来避免完全使用if
。
编辑:改进版本,修复错误。
def two_power_slice(lst):
if not lst: return lst
result = []
for i in xrange(int(math.ceil(math.log(len(lst), 2)))):
result.append(lst[2 ** i])
return result
答案 3 :(得分:1)
这是你想要做的吗?
a = [0,1,2,3,4,5,6,7,8,9]
a[1],a[2],a[4],a[8] = [11,12,14,18]
# a = [0,11,12,3,14,5,6,7,18,9]
我知道没有办法以通用的方式构建a[1],a[2],a[4],a[8]
因为理解或生成器不起作用,因为他们不承认分配操作。
答案 4 :(得分:1)
修改强>: 主要是我需要这个来修改列表。 E.g。
a[*non-linear-slicing*] = [*list-with-new-values*]
大。然后我们可以使用新值列表来驱动这个东西。演示:
>>> a = range(17)
>>> newvals = ['foo', 'bar', 'baz', 'qux']
>>> for i, val in enumerate(newvals):
a[2**i] = val
>>> a
[0, 'foo', 'bar', 3, 'baz', 5, 6, 7, 'qux', 9, 10, 11, 12, 13, 14, 15, 16]
或者如果您已经在列表中包含索引,则使用zip
而不是enumerate
:
>>> a = range(17)
>>> indexes = [1, 2, 4, 8]
>>> newvals = ['foo', 'bar', 'baz', 'qux']
>>> for i, val in zip(indexes, newvals):
a[i] = val
>>> a
[0, 'foo', 'bar', 3, 'baz', 5, 6, 7, 'qux', 9, 10, 11, 12, 13, 14, 15, 16]
既然你刚才提到来自R,也许你想使用支持这种索引的NumPy:
>>> import numpy as np
>>> a = np.arange(13)
>>> a[[1, 2, 4, 8]] = [111, 222, 444, 888]
>>> a
array([ 0, 111, 222, 3, 444, 5, 6, 7, 888, 9, 10, 11, 12])