簡體   English   中英

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM