Python对每100个元素进行迭代



我不知道这是否是一个很好的优化方法,但基本上我在3D应用程序中使用python为每个对象创建随机颜色。我的代码可以很好地处理10k多边形内的对象。但它在10万个多边形中崩溃。有没有一种方法可以通过循环中的块来实现,基本上我有for循环,并使用if语句来过滤前100个。但我还需要100,还有100,等等。我该怎么写呢?也许每个人之间都有一段时间的睡眠。它不会更快,但至少不会使程序崩溃。谢谢

for i, n in enumerate(uvShellIds):

#code can only perform well within sets of 100 elements

limit = 100 #?
if 0 <= i <= 100:
#do something
print(n)
# now I need it to work on a new set of 100 elements
#if 101 <= i <= 200:
#(...keep going between sets of 100...) 

我当前的代码:

import maya.OpenMaya as om
import maya.cmds as cmds
import random

def getUvShelList(name):
selList = om.MSelectionList()
selList.add(name)
selListIter = om.MItSelectionList(selList, om.MFn.kMesh)
pathToShape = om.MDagPath()
selListIter.getDagPath(pathToShape)
meshNode = pathToShape.fullPathName()
uvSets = cmds.polyUVSet(meshNode, query=True, allUVSets =True)
allSets = []
for uvset in uvSets:
shapeFn = om.MFnMesh(pathToShape)
shells = om.MScriptUtil()
shells.createFromInt(0)
# shellsPtr = shells.asUintPtr()
nbUvShells = shells.asUintPtr()

uArray = om.MFloatArray()   #array for U coords
vArray = om.MFloatArray()   #array for V coords
uvShellIds = om.MIntArray() #The container for the uv shell Ids

shapeFn.getUVs(uArray, vArray)
shapeFn.getUvShellsIds(uvShellIds, nbUvShells, uvset)

# shellCount = shells.getUint(shellsPtr)
shells = {}
for i, n in enumerate(uvShellIds):


#print(i,n)
limit = 100
if i <= limit:

if n in shells:
# shells[n].append([uArray[i],vArray[i]])
shells[n].append( '%s.map[%i]' % ( name, i ) )
else:
# shells[n] = [[uArray[i],vArray[i]]]
shells[n] = [ '%s.map[%i]' % ( name, i ) ]
allSets.append({uvset: shells})

for shell in shells:

selection_shell = shells.get(shell)
cmds.select(selection_shell)
#print(shells.get(shell))
facesSel = cmds.polyListComponentConversion(fromUV=True, toFace=True)
cmds.select(facesSel)
r = [random.random() for i in range(3)]
cmds.polyColorPerVertex(facesSel,rgb=(r[0], r[1], r[2]), cdo=1 )
cmds.select(deselect=1)

getUvShelList( 'polySurface359' )

您可以从itertools使用islice来chunk。

from itertools import islice
uvShellIds = list(range(1000))
iterator = iter(uvShellIds)
while True:
chunk = list(islice(iterator, 100))
if not chunk:
break
print(chunk) # chunk contains 100 elements you can process

我不知道它在你当前的代码中有多合适,但下面是你如何处理块:

from itertools import islice
uvShellIds = list(range(1000))
iterator = iter(uvShellIds)
offset = 0
while True:
chunk = list(islice(iterator, 100))
if not chunk:
break
# Processing chunk items
for i, n in enumerate(chunk):
# offset + i will give you the right index referring to the uvShellIds variable
# Then , perform your actions
if n in shells:
# shells[n].append([uArray[i],vArray[i]])
shells[n].append( '%s.map[%i]' % ( name, offset + i ) )
else:
# shells[n] = [[uArray[i],vArray[i]]]
shells[n] = [ '%s.map[%i]' % ( name, offset + i ) ]
offset += 100
# Your sleep can come here

上面的代码段应该替换您的for i, n in enumerate(uvShellIds):块。

正如@David Culbreth的回答所说,我不确定睡眠是否有帮助,但我对你可以把它放在哪里留下了评论。

我使用这个生成器来"chunkify";我在python中的长时间运行操作分成更小的批处理:

def chunkify_list(items, chunk_size):
for i in range(0, len(items), chunk_size):
yield items[i:i+chunk_size]

有了这个定义,你可以这样写你的程序:

items = [1,2,3,4,5 ...]
for chunk in chunkify_list(items, 100):
for item in chunk:
process_item(item)
sleep(delay)

现在,我不保证sleep会真正解决您的问题,但这可以让您一次处理一块数据。

最新更新