【问题标题】:How to check an item in a tuple in a tuple with inconsistent items如何在具有不一致项目的元组中检查元组中的项目
【发布时间】:2019-08-07 14:13:47
【问题描述】:

我有一个元组,其中包含一些单项以及一些更多的 2 项元组,并且我需要能够检查 2 项元组的特定匹配项。

我尝试指定 2 项元组以避免该问题,但我使用的是 django,它是一个字段集字段项,如果我指定到 2 项元组,我知道我要查找的项在,我无法执行检查正在测试的操作。出现的 django 错误是“无法为 myModel 模型表单指定,因为它是不可编辑的字段”。我也不认为我可以做一个嵌套的 for 循环,因为不是元组中的所有项目都是嵌套的元组。我还尝试将测试变量设置为该项目是否存在的布尔值,但是当我尝试执行 if 语句时会抛出错误,即使它应该被跳过,因为项目实际上存在于列表中。

我在这里和网络上查看了很多答案,但一直没有找到好的答案。

field = ('item1', 'item2', ('item3', 'item4'), 'item5')
if 'item3' not in field:
    field += ('item3', 'item5', 'item6')
    print('not there')
else:
    print('there')

# if it recognized that the item was there it would print 'there' 
# but it actually prints 'not there' and adds the items

理想情况下,这些行会看到“item3”,而不是添加其他字段并创建副本,而是添加额外的项目,因为 if/in 不能/不会进入该嵌套元组。

如果我尝试在我的 django 项目中指定内部元组(即如果 'item3' 不在字段 [2] 中),我会得到“无法为 myModel 模型表单指定,因为它是不可编辑的字段”,因为' item3' 是字段集字段中的一个项目。

所以,我想有两个具体问题: 1.当元组中有不一致的项(单项和嵌套元组)时,如何检查嵌套元组匹配? 2. 为什么知道字段集中有这个项目会抛出那个错误,因为导致它的操作应该首先被跳过?

任何人可以给我的任何帮助或建议都将非常感激和帮助!

【问题讨论】:

  • 它是field[2],因为索引是从零开始的。您可能需要首先考虑“扁平化”元组。
  • 这是一个好主意,但我将如何处理,因为没有一致的嵌套元组?从我所见,您必须执行列表理解或 for 循环将嵌套元组从嵌套中取出,但并非我的所有项目都是嵌套元组?
  • 你可以使用递归并检查 isinstance(..., tuple) 是否是一个元组。

标签: python django tuples


【解决方案1】:

如果元组具有不确定的“深度”级别(元组内部可以有元组...),您可以尝试一个简单的递归函数:

def tuple_in_recursive(field, item):
    for element in field:
        if type(element) == tuple:
            if tuple_in_recursive(element, item):
                return True
        else:
            if element == item:
                return True
    return False

如果你知道最多有 2 个级别,你可以用 2 个嵌套循环来代替,但原理是一样的。
在任何情况下,这个函数都可以推广到每个数据结构,但你似乎只有元组和基本元素,所以就足够了。

无论如何,我看到您将项目连接到元组。这不是推荐的行为,因为元组是不可变的,因此 + 运算符(附加)可能会创建一个新元组并销毁旧元组,这是非常低效的(但这取决于解释器的实现)。然后是一个可读性问题,因为看到一个元组我希望它没有被修改。
那么为什么不使用列表呢?

对于 Django 问题,我在这里看到了一个相关问题:How do you add a non-editable field to a custom admin form in Django
这似乎与单个字段(您所说的项目)有关,而不是结构本身

另一种解决方案可能是展平元组,因此您不会有任何嵌套元组。但请注意,您可能会丢失信息;也许您需要嵌套元组,代码对上面的代码稍作修改,但它不能就地工作:

def flatten(field):
    for index, element in enumerate(field):
        if type(element) == tuple:
            return field[:index] + flatten(field[index]) + flatten(field[index + 1:])
    return field

【讨论】:

  • 谢谢!正确评估该项目是否在列表中,但随后出现 django 错误。我尝试使用一个列表,但作为 django 字段集的一部分,我很确定它必须是一个元组才能正确使用。
  • @Rphillips 也许这会帮助您解决 Django 错误:stackoverflow.com/questions/45699915/… 我会更新答案
猜你喜欢
  • 1970-01-01
  • 2011-06-09
  • 2019-11-22
  • 2013-08-30
  • 1970-01-01
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多