[英]how to compare one item in a list with all the other items in this list, python
[英]Python - how to compare all items within list
作為python的首發,在遇到問題時試圖從聰明人那里獲得幫助。 那是現在:
我必須從一個列表中相互比較項目(Qt場景項目),並且使相互沖突的項目組合在一起。
請幫我代碼:
class MainWin(QMainWindow):
def __init__(self):
super(MainWin, self).__init__()
self.Win()
self.L = self.buildAllWalls()
items = self.scene.items()
allGroups = groupItemsFromList(None, items)
self.paintGroups(allGroups)
print len(allGroups)
def paintGroups(self, groups):
for g in groups :
color = QColor(0, 0, 0)
# RANDOM COLOR
namcol = "#%s" % "".join([hex(randrange(0, 255))[2:] for i in range(3)])
color.setNamedColor(namcol)
while color.isValid() == False : # ERROR CHECK
namcol = "#%s" % "".join([hex(randrange(0, 255))[2:] for i in range(3)])
color.setNamedColor(namcol)
pen = QPen(color, 14, Qt.SolidLine)
for w in g :
w.setPen(pen)
def Win(self):
self.scene = QGraphicsScene()
self.sView = QGraphicsView(self.scene)
self.sView.setRenderHint(QPainter.Antialiasing)
self.sView.setAlignment( Qt.AlignLeft | Qt.AlignTop )
self.setCentralWidget(self.sView)
self.setGeometry(20, 380, 400, 300)
self.show()
def buildAllWalls(self):
data = self.wallCoordinates()
for p in range(len(data)) :
ptA = QPointF(data[p][0], data[p][1])
ptB = QPointF(data[p][2], data[p][3])
self.wall(ptA, ptB)
def wall(self, ptA, ptB):
pen = QPen(QColor(100, 100, 100), 14, Qt.SolidLine)
currL = self.scene.addLine(QLineF(ptA.x(), ptA.y(), ptB.x(), ptB.y()))
currL.setPen(pen)
return currL
#[50,75,325,75],
def wallCoordinates(self):
data = [[50,100,150,100],[175,200,125,200],[175,275,125,275],[175,275,175,200],
[150,150,150,100],[175,100,225,100],[250,100,325,100],[350,125,175,125],
[50,125,125,125],[125,175,125,125],[150,150,175,150],[175,150,175,200],
[50,150,100,150],[100,150,100,200],[100,200,125,200],[50,175,75,175],
[75,225,75,175],[75,225,125,225],[125,275,125,225]]
return data
def main():
app = QApplication(sys.argv)
ex = MainWin()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我是這樣寫的:
def groupItemsFromList(self, itemList):
tmp = itemList[:]
allGroups = []
while tmp:
it = tmp.pop(0)
currentGroup = [it]
# loop from back to front so we can remove items safely
for i in range(len(tmp)-1, -1, -1):
if it.collidesWithItem(tmp[i]):
currentGroup.append(tmp.pop(i))
allGroups.append(currentGroup)
return allGroups
例如:
class Test(object):
def __init__(self, key):
self.key = key
def collidesWithItem(self, other):
return isinstance(other, self.__class__) and self.key == other.key
def __repr__(self):
return '{0}({1})'.format(self.__class__.__name__, self.key)
example = [Test(1), Test(2), Test(1), Test(1), Test(3), Test(2), Test(3), Test(4)]
print groupItemsFromList(None, example)
輸出:
[[Test(1), Test(1), Test(1)], [Test(2), Test(2)], [Test(3), Test(3)], [Test(4)]]
這假設所有與物品碰撞的物品也會相互碰撞。
編輯:聽起來假設無效,請嘗試以下(未經測試):
def groupItemsFromList(self, itemList):
tmp = itemList[:]
allGroups = []
while tmp:
it = tmp.pop(0)
currentGroup = [it]
i = len(tmp) - 1
while i >= 0:
if any(x.collidesWithItem(tmp[i]) for x in currentGroup):
currentGroup.append(tmp.pop(i))
i = len(tmp) - 1
else:
i -= 1
allGroups.append(currentGroup)
return allGroups
看起來你可以這樣做:
def groupItemsFromList(self, itemList): """ Make a list of lists, where each list is composed of the items (excepting itself, of course) that an item collides with. """ return [ [item for item in itemList[:i] + itemList[i:] if item.collidesWithItem(x)] for i, x in enumerate(itemList) ]
itemList[:i] + itemList[i:]
是“我想要除了第i個項目之外的原始列表的所有元素”的python習語。
后來:我明白了。 你想要更像這樣的東西:
def groupItemsFromList(self, itemList):
def collision_indexes(i, target):
return [i] + [j for j, item in enumerate(itemList[i + 1:], start=i + 1) if item.collidesWithItem(target)]
processed = set()
results = []
for i, target in enumerate(itemList):
if i not in processed:
indexes = collision_indexes(i, target)
processed.update(indexes)
results.append([itemList[j] for j in indexes])
return results
這里唯一的優點是這是無副作用的代碼。 原始數據沒有變異,只有應用於數據的函數和對新的臨時數據結構所做的更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.