Python对象列表,获取全部';方向';属性
我有一个对象列表(矩形)。每个对象有2个属性(高度和宽度)。我想得到这个列表的所有“方向”(不知道如何准确地称呼它),因此所有2^n(对于n个矩形的列表)方向,其中矩形的高度和宽度(可能)被交换。对于包含3个对象的列表,如下所示(顺序不重要): 我的矩形类如下所示:Python对象列表,获取全部';方向';属性,python,list,object,attributes,swap,Python,List,Object,Attributes,Swap,我有一个对象列表(矩形)。每个对象有2个属性(高度和宽度)。我想得到这个列表的所有“方向”(不知道如何准确地称呼它),因此所有2^n(对于n个矩形的列表)方向,其中矩形的高度和宽度(可能)被交换。对于包含3个对象的列表,如下所示(顺序不重要): 我的矩形类如下所示: class Rectangle: def __init__(self, height, width): self.height = height self.width = width
class Rectangle:
def __init__(self, height, width):
self.height = height
self.width = width
def place(self):
"""Method to place tile in a larger grid"""
def remove(self):
"""Method to remove tile from larger grid"""
有没有一种简单的方法可以做到这一点?这里有一些Python代码可以满足您的需要。如果您在
show()
函数中修复print语句,它应该可以轻松地在Python 3上运行
#!/usr/bin/env python
''' Build a list of lists containing all combinations of orientations
(i.e. landscape & portrait) for a list of Rectangle objects
From http://stackoverflow.com/q/29988288/4014959
Written by PM 2Ring 2015.05.02
'''
from itertools import product
#A simple rectangle class
class Rectangle(object):
def __init__(self, width, height):
self.width = width
self.height = height
def __repr__(self):
return 'Rectangle({0}, {1})'.format(self.width, self.height)
def transpose(self):
return Rectangle(self.height, self.width)
#Helper function to print sequences
def show(seq):
for item in seq:
print item
print
#A list of rectangle objects
rects_orig = [
Rectangle(1, 2),
Rectangle(3, 4),
Rectangle(5, 6),
]
show(rects_orig)
#The transposed versions of those rectangles
rects_rot = [rect.transpose() for rect in rects_orig]
show(rects_rot)
#Join both lists into a list of tuples
rects_both = zip(rects_orig, rects_rot)
show(rects_both)
#Build the combinations.
combos = []
for align in product([0, 1], repeat=len(rects_both)):
combos.append([rect_pair[a] for a, rect_pair in zip(align, rects_both)])
show(combos)
输出
Rectangle(1, 2)
Rectangle(3, 4)
Rectangle(5, 6)
Rectangle(2, 1)
Rectangle(4, 3)
Rectangle(6, 5)
(Rectangle(1, 2), Rectangle(2, 1))
(Rectangle(3, 4), Rectangle(4, 3))
(Rectangle(5, 6), Rectangle(6, 5))
[Rectangle(1, 2), Rectangle(3, 4), Rectangle(5, 6)]
[Rectangle(1, 2), Rectangle(3, 4), Rectangle(6, 5)]
[Rectangle(1, 2), Rectangle(4, 3), Rectangle(5, 6)]
[Rectangle(1, 2), Rectangle(4, 3), Rectangle(6, 5)]
[Rectangle(2, 1), Rectangle(3, 4), Rectangle(5, 6)]
[Rectangle(2, 1), Rectangle(3, 4), Rectangle(6, 5)]
[Rectangle(2, 1), Rectangle(4, 3), Rectangle(5, 6)]
[Rectangle(2, 1), Rectangle(4, 3), Rectangle(6, 5)]
准备:
class Rectangle:
def __init__(self, height, width):
self.height = height
self.width = width
def flipped(self):
return Rectangle(self.width, self.height)
def __repr__(self):
return 'Rectangle({}, {})'.format(self.height, self.width)
rectangles = [Rectangle(1, 10), Rectangle(2, 20), Rectangle(3, 30)]
解决方案:
from itertools import product
for orientation in product(*zip(rectangles, map(Rectangle.flipped, rectangles))):
print(orientation)
输出:
(Rectangle(1, 10), Rectangle(2, 20), Rectangle(3, 30))
(Rectangle(1, 10), Rectangle(2, 20), Rectangle(30, 3))
(Rectangle(1, 10), Rectangle(20, 2), Rectangle(3, 30))
(Rectangle(1, 10), Rectangle(20, 2), Rectangle(30, 3))
(Rectangle(10, 1), Rectangle(2, 20), Rectangle(3, 30))
(Rectangle(10, 1), Rectangle(2, 20), Rectangle(30, 3))
(Rectangle(10, 1), Rectangle(20, 2), Rectangle(3, 30))
(Rectangle(10, 1), Rectangle(20, 2), Rectangle(30, 3))
我部分地理解了你的问题,但是数据不足以为你所讨论的问题打下坚实的基础。你能说得更清楚些吗?我有一个对象列表(矩形)。这些矩形可以旋转(以便交换高度和宽度)。对于8个矩形的列表,这将导致8个矩形的2^8个不同方向。有没有一种简单的方法来生成这2^8个不同的方向?希望这能让事情变得更清楚一点。
[[R1(w,h),R2(w,h),R3(w,h)]在范围内(2**len([R1(w,h),R2(w,h),R3(w,h)])]
应该可以工作。您可以将该列表存储在变量中并使用它。这听起来像是产品
方法的工作。您还需要一个函数或方法来接收矩形并返回一个转置(旋转)的矩形。但这应该相当容易做到。你能为你的问题添加矩形类的定义吗?如果您的实际类很复杂,只需发布一个精简版本,这样我们就可以看到如何访问宽度和高度属性。这是一个好的开始:product([orientation1,orientation2],repeat=len(objects))
谢谢!这正是我想要的:)我的荣幸!这段代码可以压缩成更少的行,但我认为它在当前状态下更具可读性。此外,可能有一些更为奇特的itertools技巧,可以用更少的代码实现所需的结果,但我更喜欢直截了当的代码,而不是我在6个月内无法理解的代码。:)如果你走那么复杂的[0,1]
弯路,那就不是直截了当的。关于产品的实际直接使用,请参见我的答案。
@StefanPochmann:Good call。我应该知道不要在凌晨1点编码。:)@科恩:你应该“接受”斯特凡的回答。这比我的好,所以他应该得到(一些:)分数。好吧,我确实说过“可能会有一些更花哨的itertools技巧”。)使用map
很好;我真的需要更多的练习使用它…这不是一个把戏,虽然,这正是产品应该如何使用。你的是个骗局:-)是的,好的。我想我应该承认,我对itertools的正确使用还不太熟悉……顺便说一句,有时间来看看吧。@PM2Ring谢谢,我不知道聊天内容。我来看看。
(Rectangle(1, 10), Rectangle(2, 20), Rectangle(3, 30))
(Rectangle(1, 10), Rectangle(2, 20), Rectangle(30, 3))
(Rectangle(1, 10), Rectangle(20, 2), Rectangle(3, 30))
(Rectangle(1, 10), Rectangle(20, 2), Rectangle(30, 3))
(Rectangle(10, 1), Rectangle(2, 20), Rectangle(3, 30))
(Rectangle(10, 1), Rectangle(2, 20), Rectangle(30, 3))
(Rectangle(10, 1), Rectangle(20, 2), Rectangle(3, 30))
(Rectangle(10, 1), Rectangle(20, 2), Rectangle(30, 3))