2017-08-30 108 views
2

我想写一个函数,它将此列表的第一个元素与此列表的最后一个元素进行比较,此列表的第二个元素与此列表的第二个最后一个元素,等等。如果比较的元素相同,我想将元素添加到新列表中。最后,我想打印这个新列表。比较第一个和最后一个元素,第二个和第二个最后一个元素等的函数

例如,

>>> f([1,5,7,7,8,1]) 
[1,7] 
>>> f([3,1,4,1,5] 
[1,4] 
>>> f([2,3,5,7,1,3,5]) 
[3,7] 

我想先取(i)和去年(k)的元素,对它们进行比较,然后抬起我,但较低的K,然后重复上述过程。当我和K'重叠时,停止并打印列表。我试图想象我的想法在下面的代码:

def f(x): 
    newlist=[] 
    k=len(x)-1 
    i=0 
    for j in x: 
     if x[i]==x[k]: 
      if i<k: 
       newlist.append(x[i]) 
     i=i+1 
     k=k-1 
    print(newlist) 

请让我知道,如果有我的代码中的任何错误,或是否有解决问题的一个更合适的方式。

由于我是Python新手,在理解Python的复杂术语/特性方面我不太擅长。因此,如果您在回答中考虑了这一点,将会受到鼓励。

+0

遍历序列产生的元素,而不是指标。 –

+0

@ IgnacioVazquez-Abrams我明白了!我编辑了我的代码来解决这个问题。 – Jazzachi

+1

为什么你的第二个例子也返回[4],但第三个例子不返回[7]? (在这两种情况下,它们都是“列表中心”的元素) – FLab

回答

0

也许你想要的东西,像甚至长名单:

>>> r=[l[i] for i in range(len(l)/2) if l[i]==l[-(i+1)]] 
>>> r 
[3] 
>>> l=[1,5,7,7,8,1] 
>>> r=[l[i] for i in range(len(l)/2) if l[i]==l[-(i+1)]] 
>>> r 
[1, 7] 

而对于名单的奇长度:

>>> l=[3,1,4,1,5] 
>>> r=[l[i] for i in range(len(l)/2+1) if l[i]==l[-(i+1)]] 
>>> r 
[1, 4] 

这样你就可以创建一个功能:

def myfunc(mylist): 
    if (len(mylist) % 2 == 0): 
      return [l[i] for i in range(len(l)/2) if l[i]==l[-(i+1)]] 
    else: 
      return [l[i] for i in range(len(l)/2+1) if l[i]==l[-(i+1)]] 

并以这种方式使用它:

>>> l=[1,5,7,7,8,1] 
>>> myfunc(l) 
[1, 7] 
>>> l=[3,1,4,1,5] 
>>> myfunc(l) 
[1, 4] 
+1

我想像OP会希望解决所有问题的解决方案。 –

+0

肯定我已经完成我的帖子 – Dadep

2

你可以使用一个条件列表理解与enumerate,在指数-1-i索引i元素x比较的元素(-1是列表的最后一个索引):

>>> lst = [1,5,7,7,8,1] 
>>> [x for i, x in enumerate(lst[:(len(lst)+1)//2]) if lst[-1-i] == x] 
[1, 7] 
>>> lst = [3,1,4,1,5] 
>>> [x for i, x in enumerate(lst[:(len(lst)+1)//2]) if lst[-1-i] == x] 
[1, 4] 

或者,正如已经建议在其他答案中,请使用zip。但是,第一个参数就足够了;第二个可以是reversed列表,因为zip将在参数列表中的一个完成后停止,从而使代码更短一些。

>>> [x for x, y in zip(lst[:(len(lst)+1)//2], reversed(lst)) if x == y] 

在两种方法中,(len(lst)+1)//2相当于int(math.ceil(len(lst)/2))

+1

对于[[3,1,4,1,5]' –

+0

@ Ev.Kounis Yup失败,对于奇数编号的列表一个接一个地失败。固定。 –

0

您可以使用从zip_longest利用了以下情况:

from itertools import zip_longest 

def compare(lst): 
    size = len(lst) // 2 
    return [y for x, y in zip_longest(lst[:size], lst[-1:size-1:-1], fillvalue=None) if x == y or x is None] 

print(compare([1, 5, 7, 7, 8, 1]))  # [1, 7] 
print(compare([3, 1, 4, 1, 5]))   # [1, 4] 
print(compare([2, 3, 5, 7, 1, 3, 5])) # [3, 7] 

zip_longest

通常情况下,zip停止zip平当它的迭代器的一个用完。 zip_longest没有这个限制,它只是通过添加虚拟值来保持zip ping。

例子:

list(zip([1, 2, 3], ['a']))       # [(1, 'a')] 
list(zip_longest([1, 2, 3], ['a'], fillvalue='z')) # [(1, 'a'), (2, 'z'), (3, 'z')] 
+0

你能解释一下fillvalue和zip_longest是做什么的吗?我不熟悉itertools。 – Jazzachi

+0

@Jazzachi添加了文档和示例的链接。这很容易理解。 –

+0

'size =(len(lst)+ 1)// 2'和'zip(lst [:size],lst [-1:size-2:-1])不需要'zip_longest'' –

0

你可以做的是压缩比上半年和下半年逆转,使用列表理解来构建相同的人的名单:

[element_1 for element_1, element_2 in zip(l[:len(l)//2], reversed(l[(len(l)+1)//2:])) if element_1 == element_2] 

会发生什么是你取前半部分,并将其重复为元素_1,后半部分与元素_2相反,然后只添加它们,如果它们相同:

l = [1, 2, 3, 3, 2, 4] 
l[:len(l)//2] == [1, 2, 3] 
reversed(l[(len(l)+1)//2:])) == [4, 2, 3] 
1 != 4, 2 == 2, 3 == 3, result == [2, 3] 

如果你也想在奇数名单的情况下,中量元素,我们就可以扩大我们的名单既包括中间元素,这将始终评估一样:

[element_1 for element_1, element_2 in zip(l[:(len(l) + 1)//2], reversed(l[len(l)//2:])) if element_1 == element_2] 

l = [3, 1, 4, 1, 5] 
l[:len(l)//2] == [3, 1, 4] 
reversed(l[(len(l)+1)//2:])) == [5, 1, 4] 
3 != 5, 1 == 1, 4 == 4, result == [1, 4] 
+0

yes但是不太...看到我的答案。 –

+0

好点,我认为一个不算。我会编辑它 –

0

这里我的解决方案:

[el1 for (el1, el2) in zip(L[:len(L)//2+1], L[len(L)//2:][::-1]) if el1==el2] 

有很多事情,所以让我一步一步讲解:

  • L[:len(L)//2+1]是第一HAL列表F的加额外的元素(其是用于奇数长度的表是有用的)
  • L[len(L)//2:][::-1]是列表的第二半,反转([::-1]
  • zip创建从两个列表对的列表。它停在最短列表的末尾。我们在列表的长度是偶数的情况下使用这个,所以上半部分的额外项被忽略了
  • List comprehension基本上等于for循环,但对于创建一个“即时”列表非常有用。只有if条件为真时它才会返回一个元素,否则它会通过。

您可以轻松地修改,如果你有兴趣在指标(上半年)以上的解决方案,其中匹配发生:

[idx for idx, (el1, el2) in enumerate(zip(L[:len(L)//2+1], L[len(L)//2:][::-1])) if el1==el2] 
相关问题