筛选python列表中重复的字符串化算术运算的最佳方法?

筛选python列表中重复的字符串化算术运算的最佳方法?,python,Python,我有以下列表:['2*3=6','3*2=6','1+10/2=6.0','2/1*3=6','2*3/1=6','3/1*2=6','3*2/1=6','10/2+1=6'] 我想过滤掉与所用数字相等的方程式。我的意思是,我想得到一个方程列表,其中只包含唯一的数字组合。例如:2*3或3*2,1+10/2=6.0或10/2+1=6.0等。我还想打印出计算中未使用的数字,例如:(3*2=6未使用:1和10)等 我无法编写一个函数来实现这一点,因为我看不出我们需要比较什么。我希望这个函数在1到9之间

我有以下列表:
['2*3=6','3*2=6','1+10/2=6.0','2/1*3=6','2*3/1=6','3/1*2=6','3*2/1=6','10/2+1=6']

我想过滤掉与所用数字相等的方程式。我的意思是,我想得到一个方程列表,其中只包含唯一的数字组合。例如:2*3或3*2,1+10/2=6.0或10/2+1=6.0等。我还想打印出计算中未使用的数字,例如:(3*2=6未使用:1和10)等


我无法编写一个函数来实现这一点,因为我看不出我们需要比较什么。我希望这个函数在1到9之间工作。因此,1给出了一个列表:
['2-1=1','3-2=1','1*3-2=1','3-1*2=1','3*1-2=1','3-2*1=1','3-2*1=1','3-2/1=1']
我想用同样的方式过滤它。谢谢你的帮助

这里有一个非常简单的方法:

import re

eqs =  ['2*3=6', '3*2=6', '1+10/2=6', '2/1*3=6', '2*3/1=6', '3/1*2=6', '3*2/1=6', '10/2+1=6']

by_digits_used = {}

remaining_digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

for eq in eqs:
    used_digits = [int(f) for f in re.findall(r'\d*', eq) if f != ""]  # Find all digits in the equations
    used_digits.sort()                                                 # Ensure they're always in the same order
    used_digits = tuple(used_digits)                                   # Convert to tuple

    # Remove digits that were used
    for digit in used_digits:
        if digit in remaining_digits:
            remaining_digits.remove(digit)

    # Store equation by the digits used
    by_digits_used[used_digits] = by_digits_used.get(used_digits, []) + [eq]

print(by_digits_used)
print(remaining_digits)
结果:

# Equations by digits used
{(2, 3, 6): ['2*3=6', '3*2=6'], (1, 2, 6, 10): ['1+10/2=6', '10/2+1=6'], (1, 2, 3, 6): ['2/1*3=6', '2*3/1=6', '3/1*2=6', '3*2/1=6']}
# Unused digits
{0, 4, 5, 7, 8, 9}

您可以使用dictionary并设置如下操作

重新导入
来自itertools进口链
ls=['2*3=6','3*2=6','1+10/2=6.0','2/1*3=6','2*3/1=6','3/1*2=6','3*2/1=6','10/2+1=6']
exp='10/2+1=6'
已排序的\u nums=[已排序的([nums代表re.findall中的nums(“(\d+”,exp)])代表ls中的exp]
未使用的数量=集合(映射(str,范围(1,10))-集合(链(*已排序数量))
nums_in_exps={}
对于nums,exp in zip(已排序的nums,ls):
key=“-”。加入(nums)
如果密钥不在nums\U in\U exps中:
nums_in_exps[key]=[]
nums_in_exps[key]+=[exp]
打印(“带NUM的表达式”)
打印(nums\u in\u exps)
打印(“未使用的数字”)
打印(未使用的数量)
输出

expression with nums
{'2-3-6': ['2*3=6', '3*2=6'], '0-1-10-2-6': ['1+10/2=6.0'], '1-2-3-6': ['2/1*3=6', '2*3/1=6', '3/1*2=6', '3*2/1=6'], '1-10-2-6': ['10/2+1=6']}
unused numbers
{'8', '4', '9', '7', '5'}

使用

印刷品

Unique equations:  3*2=6 10/2+1=6 3*2/1=6
Unused numbers:  {'4', '0', '5', '9', '7', '8'}

您可以创建存储操作顺序的组的简单语法树,然后使用新的输入对象遍历该树,并尝试查找任何组匹配项:

import re
def to_tree(d):
   if len(d) == 1:
     return d[0]
   a, b, *c = d
   if b in {'*', '/'}:
      vals = [a]
      while True:
         vals.append(c[0])
         if len(c) == 1 or c[1] != b:
            c = c[1:]
            break
         c = c[2:]
      return to_tree([{'op':b, 'vals':vals}, *c])
   return {'op':b, 'vals':[a, to_tree(c)]}
现在,创建一个函数来定位各个组:

def traverse(d):
   if all(isinstance(i, str) for i in d['vals']):
      yield d
   for i in filter(lambda x:not isinstance(x, str), d['vals']):
      yield from traverse(i)

import re
exp = ['2*3=6', '3*2=6', '1+10/2=6.0', '2/1*3=6', '2*3/1=6', '3/1*2=6', '3*2/1=6', '10/2+1=6']
l = {a:list(traverse(to_tree(re.findall('\d+|[^\d]+', a.split('=')[0])))) for a in exp} 
def match(_exp, _l):
  return any(_l['op'] == i['op'] and len(_l['vals']) == len(i['vals']) and len(set(_l['vals'])&set(i['vals'])) == len(_l['vals']) for i in l[_exp])

result = [[i, [[j for j in b if match(i, j)] for a, b in l.items() if a != i]] for i in exp]
此方法生成一个列表列表,其中显示相关表达式与输入列表中所有其他表达式之间相似的操作块:

for a, b in result:
   print(a, list(filter(None, b)))
输出:

2*3=6 [[{'op': '*', 'vals': ['3', '2']}], [{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}]]
3*2=6 [[{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}]]
1+10/2=6.0 [[{'op': '/', 'vals': ['10', '2']}]]
2/1*3=6 []
2*3/1=6 [[{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}], [{'op': '*', 'vals': ['3', '2']}]]
3/1*2=6 []
3*2/1=6 [[{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}], [{'op': '*', 'vals': ['2', '3']}]]
10/2+1=6 [[{'op': '/', 'vals': ['10', '2']}]]

此解决方案的目标不仅是提供单个匹配数字,还提供实际的子运算表达式。

您能否澄清“我想过滤掉与所用数字相等的方程式”的含义。@tituszban我将其添加到问题中。这更好吗?是的。还有几件事。
6.0
6
的使用情况如何?另外,在前两项中,我认为您缺少了两个
s.@tituszban 6.0 vs 6是由除法引起的,我认为我可以使用int()获得6。我将修复
s假设这主要是字符串处理,一致使用整数将非常有用。
2*3=6 [[{'op': '*', 'vals': ['3', '2']}], [{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}]]
3*2=6 [[{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}]]
1+10/2=6.0 [[{'op': '/', 'vals': ['10', '2']}]]
2/1*3=6 []
2*3/1=6 [[{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}], [{'op': '*', 'vals': ['3', '2']}]]
3/1*2=6 []
3*2/1=6 [[{'op': '*', 'vals': ['2', '3']}], [{'op': '*', 'vals': ['3', '2']}], [{'op': '*', 'vals': ['2', '3']}]]
10/2+1=6 [[{'op': '/', 'vals': ['10', '2']}]]