Python使用lambda修改元组

Python使用lambda修改元组,python,lambda,tuples,Python,Lambda,Tuples,我有一个元组,如下所示: (((1, 1), False), ((1, top), False), ((right, 1), False), ((right, top), False)) 所以元组中有4个元组,每个元组存储一个坐标(另一个元组)和一个布尔 (我不使用dict或list,因为我需要它是可散列的) 有没有一种聪明的方法可以将给定坐标的布尔值改为真 所以我想在一行中表达的是: 在状态中将对[1]设置为True,其中对[0]=(givenX,givenY) 在python中有没有一种聪

我有一个元组,如下所示:

(((1, 1), False), ((1, top), False), ((right, 1), False), ((right, top), False))
所以元组中有4个元组,每个元组存储一个坐标(另一个元组)和一个布尔

(我不使用dict或list,因为我需要它是可散列的)

有没有一种聪明的方法可以将给定坐标的布尔值改为真

所以我想在一行中表达的是:

在状态中将对[1]设置为True,其中对[0]=(givenX,givenY)

在python中有没有一种聪明的方法可以做到这一点

更新:

谢谢你的回答。以下是我最后所做的:

state = dict(state)

if (givenX, givenY) in state.keys():
    state[(givenX, givenY)] = True

state = tuple(state.items())

由于
bool
s是不可变的(毕竟它们是纯整数),因此必须重建元组来修改它们:

tuple(x if x[0] != (givenX, givenY) else (x[0], True) for x in your_tuple)
尽管我认为最简单的方法是使用
dict
并在进行必要的修改后将其转换为
tuple

In [23]: d = {(1, 2): False}

In [24]: d[1, 2] = True

In [25]: tuple(d.items())
Out[25]: (((1, 2), True),)

由于
bool
s是不可变的(毕竟它们是纯整数),因此必须重建元组来修改它们:

tuple(x if x[0] != (givenX, givenY) else (x[0], True) for x in your_tuple)
尽管我认为最简单的方法是使用
dict
并在进行必要的修改后将其转换为
tuple

In [23]: d = {(1, 2): False}

In [24]: d[1, 2] = True

In [25]: tuple(d.items())
Out[25]: (((1, 2), True),)

显然,不能就地修改元组,但可以使用生成器表达式创建一个新元组:

given = (givenX, givenY)
result = tuple((p, p==given) for p, _ in original_tuple)
如果您已经将某些值设置为
True
,并希望保持这样:

result = tuple((p1, p2 or p1==given) for p1, p2 in original_tuple)

显然,不能就地修改元组,但可以使用生成器表达式创建一个新元组:

given = (givenX, givenY)
result = tuple((p, p==given) for p, _ in original_tuple)
如果您已经将某些值设置为
True
,并希望保持这样:

result = tuple((p1, p2 or p1==given) for p1, p2 in original_tuple)

是的,你可以用lambda函数来实现

right = 5 # dummy value
top = 7 # dummy value
search = (1,7) # needle coordinates

tups = (((1, 1), False), ((1, top), False), ((right, 1), False), ((right, top), False))

print map(lambda x: (x[0], not x[1]) if x[0]==search else (x[0], x[1]), tups)
# [((1, 1), False), ((1, 7), True), ((5, 1), False), ((5, 7), False)]
但是,这将产生一个元组列表,因此需要再次将其转换为元组

print tuple(map(lambda x: (x[0], not x[1]) if x[0]==search else (x[0], x[1]), tups))
# (((1, 1), False), ((1, 7), True), ((5, 1), False), ((5, 7), False))

是的,你可以用lambda函数来实现

right = 5 # dummy value
top = 7 # dummy value
search = (1,7) # needle coordinates

tups = (((1, 1), False), ((1, top), False), ((right, 1), False), ((right, top), False))

print map(lambda x: (x[0], not x[1]) if x[0]==search else (x[0], x[1]), tups)
# [((1, 1), False), ((1, 7), True), ((5, 1), False), ((5, 7), False)]
但是,这将产生一个元组列表,因此需要再次将其转换为元组

print tuple(map(lambda x: (x[0], not x[1]) if x[0]==search else (x[0], x[1]), tups))
# (((1, 1), False), ((1, 7), True), ((5, 1), False), ((5, 7), False))

听起来您已经到了将数据封装在一组类中的好主意

您可以将其用作类的基础,这些类将创建不可变的对象,很容易为这些对象创建一个具有一个或多个不同值的新实例。您甚至可以对您创建的namedtuple进行子类化,并添加自己的方法,这将有助于轻松替换对象中的值,同时保持代码简洁易读

from collections import namedtuple

right = "right"
top = "top"
tuple_data = (((1, 1), False), ((1, top), False), ((right, 1), False), ((right, top), False))

# create a subclass of tuple whose name is the first argument, and the second argument 
# is space separated fields which are aliases for accessing the class as a tuple.
# eg. Point(1, 2).x == Point(1, 2)[0]
Point = namedtuple("Point", "x y")
_PointValueBase = namedtuple("PointValue", "point value")
_RectangleBase = namedtuple("Rectangle", "leftbottom lefttop rightbottom righttop")

class PointValue(_PointValueBase):
    def replace_if_point_equal(self, point, value):
        if self.point == point:
            return self._replace(value=value)
        return self

class Rectangle(_RectangleBase):
    def replace(self, point, value):
        return Rectangle._make(pv.replace_if_point_equal(point, value) for pv in self)

# convert tuple_data to a Rectangle
rect = Rectangle(*(PointValue(Point(*p), v) for p, v in tuple_data))
print(rect) # nice textual representation
assert eval(str(rect)) == rect # which is also machine readable
assert isinstance(rect, tuple) # is a subclass of tuple
assert hash(tuple_data) == hash(rect) # so its hash is the same

given_point = Point(x=right, y=top)
new_rect = rect.replace(given_point, value=True)
print(new_rect)
assert new_rect.righttop.value is True

听起来您已经到了将数据封装在一组类中的好主意

您可以将其用作类的基础,这些类将创建不可变的对象,很容易为这些对象创建一个具有一个或多个不同值的新实例。您甚至可以对您创建的namedtuple进行子类化,并添加自己的方法,这将有助于轻松替换对象中的值,同时保持代码简洁易读

from collections import namedtuple

right = "right"
top = "top"
tuple_data = (((1, 1), False), ((1, top), False), ((right, 1), False), ((right, top), False))

# create a subclass of tuple whose name is the first argument, and the second argument 
# is space separated fields which are aliases for accessing the class as a tuple.
# eg. Point(1, 2).x == Point(1, 2)[0]
Point = namedtuple("Point", "x y")
_PointValueBase = namedtuple("PointValue", "point value")
_RectangleBase = namedtuple("Rectangle", "leftbottom lefttop rightbottom righttop")

class PointValue(_PointValueBase):
    def replace_if_point_equal(self, point, value):
        if self.point == point:
            return self._replace(value=value)
        return self

class Rectangle(_RectangleBase):
    def replace(self, point, value):
        return Rectangle._make(pv.replace_if_point_equal(point, value) for pv in self)

# convert tuple_data to a Rectangle
rect = Rectangle(*(PointValue(Point(*p), v) for p, v in tuple_data))
print(rect) # nice textual representation
assert eval(str(rect)) == rect # which is also machine readable
assert isinstance(rect, tuple) # is a subclass of tuple
assert hash(tuple_data) == hash(rect) # so its hash is the same

given_point = Point(x=right, y=top)
new_rect = rect.replace(given_point, value=True)
print(new_rect)
assert new_rect.righttop.value is True

在状态集pair[1]中,如果pair[0]=(givenX,givenY),那么将pair[1]设置为True是什么意思?@AvinashRaj这听起来很清楚。如果索引0(
pair[0]
)处的值是
(givenX,givenY)
,请将索引1(
pair[1]
)处的元组值设置为
@MarkusMeskanen确切地说,谢谢您可能想查看。在状态中将pair[1]中的
设置为True是什么意思,其中pair[0]=(givenX,givenY)
?@AvinashRaj这听起来很清楚。如果索引0(
pair[0]
)处的值正好是
(givenX,givenY)
@MarkusMeskanen,则将索引1(
pair[1]
)处的元组值设置为
True
,谢谢你,你可能想看看。虽然这个答案可能是最好的解决方案,但它不符合OP的问题。他要求对lambda这样做,所以我真的不明白他为什么接受这个答案。同样,这个答案只适用于将布尔值从false设置为true,而不是相反。@kasperTaeymans我想他们已经说得很清楚了——“将pair[1]设置为true”,虽然这个答案可能是最好的解决方案,但它不符合OP的问题。他要求对lambda执行此操作,所以我真的不明白他为什么接受这个答案。同样,这个答案只适用于将布尔值从false设置为true,而不是相反。@kasperTaeymans我想他们已经说得很清楚了——“将pair[1]设置为true”