Python脚本,它将两个整数列表作为输入,并返回第一个列表中一个单元内的第二个列表的子集?

时间:2015-04-02 19:25:42

标签: python list bioinformatics

这是我到目前为止所做的:

list1= raw_input('Enter first list of integers, with comma after each number: ')
list2 = raw_input('Enter second list of integers, with comma after each number: ')
list1 = list1.split(',') #makes lists
list2 = list2.split(',')

list1 = (int(x) for x in list1) #turns them into integers
list2 = (int(x) for x in list2)

secondlist = []

for x in list2:
    if x == 
while x in list2 == list1[x]+1 or list1[x]-1:

我无法弄清楚如何使用list2中的一个项目检查list1中的每个项目。

7 个答案:

答案 0 :(得分:1)

循环遍历第二个列表,然后遍历第一个列表,检查两个数字的绝对值是0还是1,如果为真,则添加到结果列表中。

示例:

l1 = [1, 2, 3, 4]
l2 = [4, 5, 7, 0, 75]
matches = []
for i2 in l2:
    for i1 in l1:
        if abs(i1 - i2) <= 1:
            matches.append(i2)
            break

matches[4, 5, 0]

如果您对单行感兴趣:

[y for y in l2 if any(abs(x - y) <= 1 for x in l1)]

使用您的代码实现此操作看起来像

list1 = raw_input('Enter first list of integers, with comma after each number: ').split(',')
list2 = raw_input('Enter second list of integers, with comma after each number: ').split(',')
list1 = map(int, list1)
list2 = map(int, list2)
secondlist = [y for y in l2 if any(abs(x - y) <= 1 for x in l1)]

答案 1 :(得分:1)

嗯,这不是简单的,但你可以用两个列表理解来做。

import itertools

# lst1 and 2 are already ints

valid_numbers = set(itertools.chain.from_iterable([(num-1, num, num+1) for num in lst1]))
result = [num for num in lst2 if num in valid_numbers]

这只会在lst1两次和lst2之间循环一次,而不是循环lst1次N次(lst2中每个元素一次)。因此,随着lst2的增长,它应该快得多。

答案 2 :(得分:0)

# Let's suppose you already have the lists
list1 = [1,2,3,4,5]
list2 = [1,2,3,4,5, 2,3,4, 2]


# Count occurences
occurences = {}
for item in list2:
    if item in occurences:
        occurences[item]+=1
    else:
        occurences[item]=1

ones = set([])
for item in list1:
    if (occurences.get(item+1,0)>0) or (occurences.get(item-1,0)>0):
        ones.add(item)
print ones

答案 3 :(得分:0)

“第一个列表中的一个单元内”是什么意思?以下是我对这句话的理解。

def within_one(xlist, x):
    within = False
    for i in xlist:
        if x >= i-1 and x =< i+1:
            within = True
            break
    return within

print([j for j in list2 if within_one(list1, j)])

答案 4 :(得分:0)

或多或少与上面基于绝对值的单线程相同,但对我来说一目了然。

>>> lst1 = [2, 3, 4, 5, 6]
>>> lst2 = [4, 5, 6, 7, 8]
>>> [n for n in lst2 if n in lst1 or n+1 in lst1 or n-1 in lst1]
[4, 5, 6, 7]

答案 5 :(得分:0)

这个应该是O(2n *(1 + log(n))):对输入列表进行排序,每个列表需要O(n log(n)),然后两个列表只运行一次,O(n)。

mk_nm    = lambda nm: "Enter {0}> ".format( nm )
readlist = lambda nm: sorted(map(int, raw_input(mk_nm(nm)).strip().split(',')))

# read the input lists and transform them into sorted lists of ints
list1    = readlist("list1")
list2    = readlist("list2")

# The accumulator holds the output list and 
# the current list1
def reductor(acc, l2item):
    (output, l1) = acc
    # process elements from l1 until we find one
    # that is > current l2 item-1
    for i in xrange(len(l1)):
        if abs(l1[i] - l2item)<=1:
            output.append(l2item)
        if l1[i]>=l2item-1:
            break
    # remove elements from l1 that we processed
    return (output, l1[i:])

found = reduce(reductor, list2, ([], list1))[0]
print "Found: ",found

试一试:

Enter list1> 1,2,3,4
Enter list2> 4,5,7,0,70
Found:  [0, 4, 5]

答案 6 :(得分:-1)

编辑原始答案...... 双列表理解对此有用。作为算法,它是O(n ^ 2)。

list1 = [10, 20, 30, 40]
list2 = [8, 21, 32, 39]

print [x for x in list2 for y in list1 if abs(x-y) <= 1]

如果您发现要比较的列表非常大,或者您一次设置list1并重复使用list2或其他列表进行搜索,则可以考虑切换到字典,也称为哈希表

l1 = [x+1 for x in list1] #Just building the lists
l2 = [x-1 for x in list1] #
list1.extend(l1)
list1.extend(l2)  #list1 now has x, x-1, and x+1 for each x

d = dict(zip(list1, list1))

print [x for x in list2 if x in d]

字典将首先用于构建字典的O(n),然后在此之后进行平均O(1)搜索。需要考虑的事情。