Python 获取列表的每一部分

Python 获取列表的每一部分,python,Python,我已经通过了itertools的内部和外部,我不知道如何做到以下几点。我想要一张单子 x=[1,2,3,4,5,6,7,8]我想得到一个新列表: y = [[1],[1,2],[1,2,3],.......[2],[2,3],[2,3,4].....[8]] 我需要一个所有切片的列表,但不是组合或排列 x=list(zip(x[::2],x[1::2])很接近,但并没有达到我所希望的那样使用组合而不是x,而是可能的切片索引的范围(包括一个超过末端的,因此len(x)+1,因为切片在末端是独占的

我已经通过了itertools的内部和外部,我不知道如何做到以下几点。我想要一张单子

x=[1,2,3,4,5,6,7,8]
我想得到一个新列表:

y = [[1],[1,2],[1,2,3],.......[2],[2,3],[2,3,4].....[8]]
我需要一个所有切片的列表,但不是组合或排列


x=list(zip(x[::2],x[1::2])
很接近,但并没有达到我所希望的那样使用
组合
而不是
x
,而是可能的切片索引的
范围
(包括一个超过末端的,因此
len(x)+1
,因为切片在末端是独占的)来形成切片端点,然后使用它们来切片
x

from itertools import combinations

y = [x[s:e] for s, e in combinations(range(len(x)+1), 2)]
这正是你想要的,尽可能直截了当。如果希望(可能)更快地映射基于
的代码,可以将其重新表述为(
list
在Python 2上不需要包装器):

这会得到相同的结果,但每个项都没有任何Python字节码执行,这可能会运行得更快(取决于实现)。

您可以尝试以下方法:

x = [1,2,3,4,5,6,7,8]
y = [x[b:i+1] for b in range(len(x)) for i in range(len(x))]
final_list = list(filter(lambda x:x, y))
输出:

[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7, 8], [2], [2, 3], [2, 3, 4], [2, 3, 4, 5], [2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [2, 3, 4, 5, 6, 7, 8], [3], [3, 4], [3, 4, 5], [3, 4, 5, 6], [3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8], [4], [4, 5], [4, 5, 6], [4, 5, 6, 7], [4, 5, 6, 7, 8], [5], [5, 6], [5, 6, 7], [5, 6, 7, 8], [6], [6, 7], [6, 7, 8], [7], [7, 8], [8]]

如果坚持一行,您可以利用列表理解:

> x=[1,2,3,4]
> [x[a:b+1] for a in range(len(x)) for b in range(len(x)) if a<=b]

我认为这是一种很好的方法,一种迭代的方法,我能很好地理解它:

lst = [1,2,3,4,5,6,7,8]

res = []
ln= len(lst)


for n in range(ln):
  for ind in range(n+1, ln+1):
    res.append(lst[n:ind])

那不是有效的代码;您的
for
s是向后的(在它存在之前使用
i
)。即使翻转它们,也不会产生您声称的输出。请再试一次,但请先运行
deli
。相信我,这是错误的。在定义
i
之前,不能使用
i
来创建
范围
,并且您无意中依赖了
i
之前的定义。另外,旁注:
filter(lambda x:x,…)
是编写
filter(None,…)
的一种(慢得多的)方法<当谓词为
None
@ShadowRanger对不起,在我的终端中有一个
i
变量定义在100行以上时,记录code>filter
以使用身份测试!请看我最近的编辑。它现在可以工作了。@Ajax1234。您的输出与OP要查找的内容不匹配。@ShadowRanger。我认为这并不完全公平,因为只有在python-2.6中才添加了
itertools.combines
。不管怎么说,我认为他的答案值得投一票,即使它不能提供最有效的解决方案。它似乎提供了最具可读性的解决方案。您可以通过将范围更改为
range(len(lst))
(外部
range
),来限制循环并避免空测试,因为开始索引应始终在0和len(lst)-1之间,并且
range(n+1,len(lst)+1)
(内部
range
)因为“结束”必须始终至少比“开始”大一个,并且必须在刚好超过
列表的结束时停止,才能切到结尾。那么你根本不需要
if
测试。@ShadowRanger aaaaaaah,我明白了!谢谢,当你完成编辑时我正在编辑,非常感谢,顺便说一句,至少在我的CPython 3.5安装中,listcomp对于示例输入(长度8
list
)更快(仅为2%),但随着输入的增长,其伸缩性稍差(对于长度100
list
,它比“push to C”慢约5%
map
based解决方案)。也就是说,listcomp对我来说更具可读性,所以我一般更喜欢它。我把另一个放在那里只是为了好玩。这包括开始大于或等于结束的片段吗?@jpmc26:不,因为这会在输出中产生一堆空的
列表
combines
返回输入的按字典顺序排列的组合(不替换),因此它通过
1
len(x)
(包括+1),然后通过
2
len(x)
等生成
0
。与
范围内的嵌套循环不同,它也不必创建一堆具有不同边界的
range
对象(在内部循环中),这节省了更多Python级别的工作并避免了临时性(它返回的两个
tuple
s被缓存和重用,因此它们实际上不需要任何成本)。我理解。混淆了排列和组合但我认为你的解释不太中肯。它们被排序的唯一原因是
range
的输出为。例如,尝试使用组合(排序(范围(8+1),反向=真),2)
。然后所有元组将以较大的值开始<代码>组合
似乎是按照输入的顺序进行的,因此这取决于
范围
@jpmc26的细节:术语很混乱(涉及两种顺序,元组顺序和元组内顺序),但需要明确的是:
元组
以字典顺序发出,但它们本身只有在输入同样正确的情况下才是内部有序的。根据文档:“组合是按字典排序顺序发出的。因此,如果对输入的iterable进行排序,组合元组将按排序顺序生成。”因此,是的,
range
有序是很重要的,但这是标准
range
的一个属性,我觉得不需要解释。
> [x[a:b+1] for a in range(len(x)) for b in range(a, len(x))]
lst = [1,2,3,4,5,6,7,8]

res = []
ln= len(lst)


for n in range(ln):
  for ind in range(n+1, ln+1):
    res.append(lst[n:ind])