繁体   English   中英

检查元素是否在列表中

[英]check whether an element is in list or not

我有一个矩阵或列表列表:

x = [[1,2,3], 
     [2,3,1], 
     [3,1,2]]

我的目标是检查

1)矩阵的每一列都包含一个从1到n的整数。

2)矩阵的每一行仅包含一次从1到n的整数。

这是我在解决Udacity编程入门课程时遇到的问题练习。 这是我解决问题的方法。 我知道这很长而且效率很低。 那么解决这个问题的快捷有效方法是什么呢?

def check(p):
    j = 0
    for e in p:
        i = 1 + j
    s = str(p)

    if s.find('.')!= -1:
        return False

    while i < len(p):
        if p[i] == e:
            return False
        if p[i] > len(p) or p[i] < 1:
            return False
        i += 1
        j += 1
    return True

def check_sudoku(p):
    i = 0
    z = []
    a = []
    x = 0
    for e in p:
        r = check(e)
        if r == False:
            return r

    #Below here is to transpose the list
    while x < len(p):
        z.append(1)
        x += 1
    while i < len(p):
        for e in p:
            a.append(e.pop())
        z[i] = a
        i +=  1
        a = []

    #Below here is to check the transpose
    for g in z:
        r = check(g)
        if r == False:
            return r
    return True

您可以像这样简化检查程序:

def check_valid(matrix):
    n = len(matrix[0])
    valid_num = range(1, n+1)     # make a list of valid number from 1 to n

    # sort rows and column of matrix in ascending order and compare with valid_num 
    for line in matrix:
        if sorted(line) != valid_num:
            return False
    for column in zip(*matrix):
        if sorted(column) != valid_num:
            return False

    # If all rows and column is valid, then 
    return True 

编辑 :遵循@vocalno KISS规则,但速度更快,适用于数字和字符

def check_valid2(matrix):
    n = len(matrix)

    for line in matrix+zip(*matrix):
        if len(set(line)) != n:
            return False

    return True

In[9]: %timeit for m in (x, y): check_valid_mine(m)
100000 loops, best of 3: 8.55 µs per loop

In[10]: %timeit for m in [x,y]: check_valid2(m)
100000 loops, best of 3: 5.77 µs per loop

编辑2:关于速度的一切

def check_valid3(matrix):
    n = len(matrix)

    for line in matrix+zip(*matrix):
        if not len(set(line)) - n:
            return False

    return True

In[19]: %timeit for m in [x,y]: check_valid3(m)
100000 loops, best of 3: 2.29 µs per loop

这是我的解决方案

我循环浏览行和列,使用zip来翻转矩阵和 -合并2个列表。 如果行或列包含的值都不在valid_set中

set(row) - valid_set

表达将产生非空集合-通过转向 -和所有循环将结束

from itertools import chain
def check_valid(matrix, n):
   valid_set = set(range(1, n+1))
   return all(not(set(row) - valid_set) for row in chain(matrix, zip(*matrix)))

编辑:
对不起,看错了问题; 这是正确的答案- 所有出现在第一个False上的出口

from itertools import chain
def check_valid(matrix):
   valid_set = set(range(1, len(matrix)+1))
   return all(set(row) == valid_set for row in chain(matrix, zip(*matrix)))

编辑2:

出于好奇-我定时排序设置方法

In [74]: x = [[1,2,3], 
   ....:      [2,3,1], 
   ....:      [3,1,2]]

In [79]: %timeit for row in x: sorted(row)
1000000 loops, best of 3: 1.38 us per loop

In [80]: %timeit for row in x: set(row)
1000000 loops, best of 3: 836 ns per loop

设置快约30%

编辑3:我修复了危险的解决方案并更新了我的

In [132]: def check_valid(matrix):
    valid_num = np.unique(np.array(matrix)).tolist() # selects unique elements
    for line in matrix:
        if sorted(line) != valid_num:
            return False
    for column in zip(*matrix):
        if sorted(column) != valid_num:
            return False
    return True
In [136]: %timeit for m in (z, d): check_valid(m)
10000 loops, best of 3: 57.8 us per loop

In [115]: def check_valid_mine(matrix):                                                  
       valid_set = set(chain(*matrix))
       return all(set(row) == valid_set for row in chain(matrix, zip(*matrix)))

In [137]: %timeit for m in (z, d): check_valid_mine(m)
100000 loops, best of 3: 8.96 us per loop

底线? 吻-保持简单愚蠢

通过zip()解释矩阵转置

  • 函数调用中可迭代参数之前的运算符,基本上会扩展此位置参数的参数列表

    邮编(*矩阵)

手段

zip(matrix[0], matrix[1], matrix[2], ...)

因此将列重新排列为行请查看此答案,以详细了解*和**运算符

我正在寻找一个完全匹配字符和数字的解决方案,并且我使用了numpy库来提供一个解决方案。 我稍微修改了Dragon2fly解决方案。 如果我错了,请纠正我。 我检查了z和d值的解,并给出了正确的结果。

 import numpy as np

z = [[8,9,10],  # example case with numbers
     [9,10,8], 
     [10,8,9]]


d =  [['a','b','c'], # example case with characters
      ['b','c','a'],
      ['c','a','b']]

def check_valid(matrix):
    valid_num = list(np.unique(matrix)) # selects unique elements


    # sort rows and column of matrix in ascend order and compare with valid_num 
    for line in matrix:
        if sorted(line) != valid_num:
            return False
    for column in zip(*matrix):
        if sorted(column) != valid_num:
            return False

    # If all rows and column is valid, then 
    return True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM