Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python子列表上循环并使其增长的最有效方法(插入方法)?_Python_Algorithm - Fatal编程技术网

在Python子列表上循环并使其增长的最有效方法(插入方法)?

在Python子列表上循环并使其增长的最有效方法(插入方法)?,python,algorithm,Python,Algorithm,我的问题是如何管理循环中的插入/附加方法 我有两个长度N:第一个(我们称之为s)表示要计算的子集,而第二个表示要计算的数量x。为了简单起见,假设每个子集都表示T元素 cont = 0; for i in range(NSUBSETS): for j in range(T): subcont = 0; if (x[(i*T)+j] < 100): s.insert(((i+1)*T)+cont, s[(i*T)+j+cont])

我的问题是如何管理循环中的插入/附加方法

我有两个长度
N
:第一个(我们称之为
s
)表示要计算的子集,而第二个表示要计算的数量
x
。为了简单起见,假设每个子集都表示T元素

cont = 0;
for i in range(NSUBSETS):
    for j in range(T):
        subcont = 0;
        if (x[(i*T)+j] < 100):
            s.insert(((i+1)*T)+cont, s[(i*T)+j+cont]);
            x.insert(((i+1)*T)+cont, x[(i*T)+j+cont]);
            subcont += 1;
    cont +=  subcont;
cont=0;
对于范围内的i(NSUBSETS):
对于范围(T)内的j:
分包=0;
如果(x[(i*T)+j]<100):
s、 插入((i+1)*T)+cont,s[(i*T)+j+cont]);
x、 插入((i+1)*T)+cont,x[(i*T)+j+cont]);
分包+=1;
cont+=分包合同;
在循环遍历两个列表的所有元素时,我希望在满足某个条件(例如
x[I]<100
)时,该元素的一个副本放在子集的末尾,然后继续循环,直到完成对子集的所有原始成员的分析。维护“顺序”是很重要的,即在它来自的子集的最后一个元素旁边插入元素


我认为有一种方法可以在两个计数器变量中分别存储子集内和全局内的副本数(请参见代码):这样,我可以根据这一点移动我正在查看的元素的索引。我想知道是否有更简单的方法可以做到这一点,也许可以使用一些Python魔法。

我倾向于复制您的列表,然后,当您遇到插入标准时,在需要的地方插入副本。然后,您可以输出复制和更新的列表。

一种可能是使用numpy的高级索引,通过为原始列表创建一个“复制”索引列表,并将其添加到表示每个子集的索引/切片列表中,从而提供将元素复制到子集末端的错觉。然后,您将在最后合并所有索引/切片列表,并使用最终的索引列表访问所有项目(我相信也支持使用生成器样式,这可能会对高级索引/切片返回副本而不是视图很有用)。取决于有多少元素符合要复制的标准,这应该是相当有效的,因为每个子集都将其索引作为切片对象,从而减少跟踪所需的索引数量。

我认为找到了一个简单的解决方案。 我从最后一个子集向后循环,将副本放在每个子集的末尾。这样,我就避免了遇到“新”元素,摆脱了计数器和similia

范围内的i的
(NSUBSETS-1,-1,-1):
对于范围(T-1,-1,-1)内的j:
如果(x[(i*T)+j]<100):
s、 插入((i+1)*T),s[(i*T)+j])
x、 插入((i+1)*T),x[(i*T)+j])

如果您的想法是在列表中插入额外的副本,而不制作整个列表的完整副本,您可以尝试使用一个新的方法。在循环浏览列表时,收集要附加的匹配项。在处理每一个项目的过程中产生它,然后也产生每一个收集到的项目

这是一个只有一个列表的简化示例,但希望它能说明这个想法。只有当你像我一样理解并扩展生成器时,你才会得到一份副本。如果您只想存储或进一步分析处理后的列表(例如,将其写入磁盘),则根本无法将其存储在内存中

def append_matches(input_list, start, end, predicate):
  # where predicate is a filter function or lambda
  for item in input_list[start:end]:
    yield item
  for item in filter(predicate, input_list[start:end]): 
    yield item

example = lambda p:  p < 100
data = [1,2,3,101,102,103,4,5,6,104,105,106]

print [k for k in append_matches (data, 0, 6, example)]
print [k for k in append_matches (data, 5, 11, example)]

[1, 2, 3, 101, 102, 103, 1, 2, 3]
[103, 4, 5, 6, 104, 105, 4, 5, 6]
def append_匹配(输入_列表、开始、结束、谓词):
#其中谓词是筛选函数或lambda
对于输入列表中的项目[开始:结束]:
收益项目
对于筛选器中的项(谓词,输入_列表[开始:结束]):
收益项目
示例=λp:p<100
数据=[1,2,3101102103,4,5,6104105106]
打印[k表示附加匹配中的k(数据,0,6,示例)]
打印[k表示附加匹配中的k(数据,5,11,示例)]
[1, 2, 3, 101, 102, 103, 1, 2, 3]
[103, 4, 5, 6, 104, 105, 4, 5, 6]

我猜你不想复制这些列表是基于你的C语言背景——这是一种假设,这样做会更加昂贵。在Python中,列表实际上不是列表,插入有O(n)时间,因为它们更像向量,所以这些插入操作都在复制列表

用额外的元素构建一个新副本将比尝试就地更新更有效。如果你真的想这样做,你需要编写一个LinkedList类来保存prev/next引用,这样你的Python代码就是C方法的副本

最具python风格的方法不会尝试执行就地更新,因为使用值而不是引用来表示所需内容更简单:

def expand(origLs) :
  subsets = [ origLs[i*T:(i+1)*T] for i in range(NSUBSETS) ]
  result = []
  for s in subsets :
    copies = [ e for e in s if e<100 ]
    result += s + copies
  return result
def扩展(origLs):
子集=[origLs[i*T:(i+1)*T]表示范围内的i(nsubset)]
结果=[]
对于子集中的s:

copies=[e代表e,in s如果eThanks代表你的答案,我明白你的意思。无论如何,我希望有人能提出另一种方法,而不必复制列表。你是否有C语言背景?你唯一应该在语句末尾加分号的时候是在同一行有另一个语句时。(如果你愿意的话,你也可以用另一种方法,从uu future uuu import brages
中使用
,来真正获得C风格的感觉。)没错,我应该改掉这个习惯…:-)我不知道在同一行中有多个语句,谢谢你的提示!不客气。(请注意,我是在和来自uu future uuuu导入大括号的
开玩笑,它实际上不起作用。)啊哈,我没有得到它!:-D无论如何,我发誓我没有试过!从技术上讲,这些的生成器表达式应该是
(输入列表中的项对应于项[start:end])
(输入列表中的项对应于项[start:end]如果谓词(项))
,您正在使用一个成熟的生成器函数。此外,对于大型子集,使用
itertools.islice()
itertoo可能更有效
def expand(origLs) :
  subsets = [ origLs[i*T:(i+1)*T] for i in range(NSUBSETS) ]
  result = []
  for s in subsets :
    copies = [ e for e in s if e<100 ]
    result += s + copies
  return result