(Usando python 3) Aquí está la tarea que me han asignado:

Dada una lista de números, encuentre e imprima todos sus elementos que sean mayores que su vecino izquierdo.

Entrada de ejemplo

1 5 2 4 3

Salida de ejemplo

5 4

Aquí está mi código:

# creates a list out of the input given as '# # # # # #...'
a = [int(s) for s in input().split()]

for i in a[1:]:               #skips the first since it has no "left neighbor"
   if i > a[a.index(i) - 1]:  #checks if 'i' is greater than element before 'i'
      print(i, end=' ')

Mi problema es que funciona para todas las pruebas que hago, excepto si le doy una lista donde a[0] == a[-1] luego ignora todos los elementos en la lista igual a ese entero.

Por ejemplo:

3 5 2 3 1 2 3 1 3
--> 5    

¡He estado teniendo dificultades para encontrar el error! Disculpe si esta pregunta no está bien presentada. Es la primera vez que hago una pregunta sobre stackoverflow.

2
Levi Baguley 25 feb. 2018 a las 10:57

4 respuestas

La mejor respuesta

Prueba esto:

for i in range(1, len(a)):
    if a[i] > a[i-1]:
        print(a[i], end=' ')

Resultado:

3 5 2 3 1 2 3 1 3
--> 5 3 2 3 3
5
Mushif Ali Nawaz 25 feb. 2018 a las 08:02

Usando filter y lambda:

lst = [3, 5, 2, 3, 1, 2, 3, 1, 3]

greater = [item[1] for item in filter(lambda x: x[1] > x[0], zip(lst, lst[1:]))]
print(greater)

Lo que produce

[5, 3, 2, 3, 3]

O, como comenta @Roadrunner (¡mi favorita!):

[y for x, y in zip(lst, lst[1:]) if y > x]

Solo para confundir a las masas, también podrías escribir tu propia función de generador:

def greater(iterable):
    ilst = iter(iterable)
    prev, current = None, next(ilst)
    while (ilst):
        if prev and current > prev:
            yield current
        prev, current = current, next(ilst)

greater_n = [g for g in greater(lst)]
print(greater_n)

def mushif():
    lst = [3, 5, 2, 3, 1, 2, 3, 1, 3]
    greater = []
    for i in range(1, len(lst)):
        if lst[i] > lst[i-1]:
            greater.append(lst[i])

def jan():
    lst = [3, 5, 2, 3, 1, 2, 3, 1, 3]
    greater = [item[1] for item in filter(lambda x: x[1] > x[0], zip(lst, lst[1:]))]


def roadrunner():
    lst = [3, 5, 2, 3, 1, 2, 3, 1, 3]
    greater = [y for x, y in zip(lst, lst[1:]) if y > x]

import timeit

print(timeit.timeit(mushif, number=10**5))
print(timeit.timeit(jan, number=10**5))
print(timeit.timeit(roadrunner, number=10**5))

Rendimientos

0.37175918000139063
0.49957343799906084
0.2700801329992828
4
Jan 25 feb. 2018 a las 20:52

Una solución más sin usar zip o acceder al elemento cada vez por su índice

prev, *lst = [3, 5, 2, 3, 1, 2, 3, 1, 3]
greater = []
for i in lst:
    if prev < i:
        greater.append(i)
    prev = i

Y casos de prueba como @Jan presentó:

def mushif(lst):
    greater = []
    for i in range(1, len(lst)):
        if lst[i] > lst[i-1]:
            greater.append(lst[i])

def jan(lst):
    greater = [item[1] for item in filter(lambda x: x[1] > x[0], zip(lst, lst[1:]))]


def roadrunner(lst):
    greater =   [y for x, y in zip(lst, lst[1:]) if y > x]

def vishes_shell(lst):
    start, *lst = lst
    greater = []
    for i in lst:
        if start < i:
            greater.append(i)
        start = i

import timeit, functools, random
lst = [3, 5, 2, 3, 1, 2, 3, 1, 3]
print('Runnig with {} elements'.format(lst))
print('mushif', timeit.timeit(functools.partial(mushif, lst), number=10**5))
print('jan', timeit.timeit(functools.partial(jan, lst), number=10**5))
print('roadrunner', timeit.timeit(functools.partial(roadrunner, lst), number=10**5))
print('vishes_shell', timeit.timeit(functools.partial(vishes_shell, lst), number=10**5))

lst = [random.randint(1, 100) for _ in range(100)]
print('Runnig with 100 elements')
print('mushif', timeit.timeit(functools.partial(mushif, lst), number=10**5))
print('jan', timeit.timeit(functools.partial(jan, lst), number=10**5))
print('roadrunner', timeit.timeit(functools.partial(roadrunner, lst), number=10**5))
print('vishes_shell', timeit.timeit(functools.partial(vishes_shell, lst), number=10**5))

lst = [random.randint(1, 100) for _ in range(1000)]
print('Runnig with 1000 elements')
print('mushif', timeit.timeit(functools.partial(mushif, lst), number=10**5))
print('jan', timeit.timeit(functools.partial(jan, lst), number=10**5))
print('roadrunner', timeit.timeit(functools.partial(roadrunner, lst), number=10**5))
print('vishes_shell', timeit.timeit(functools.partial(vishes_shell, lst), number=10**5))

Salidas:

Runnig with [3, 5, 2, 3, 1, 2, 3, 1, 3] elements
mushif 0.22174075798830017
jan 0.367339823016664
roadrunner 0.16411117801908404
vishes_shell 0.16474426098284312

Runnig with 100 elements
mushif 1.8483440639975015
jan 2.6946504779916722
roadrunner 0.8267438650073018
vishes_shell 1.1597095750039443

Runnig with 1000 elements
mushif 21.29723681899486
jan 26.859666333009955
roadrunner 8.274298987002112
vishes_shell 12.677083582995692

Como puedes ver, roadrunner es la mejor.

3
vishes_shell 25 feb. 2018 a las 12:23
a = [5, 2, 3, 1, 2, 3, 1, 3]
[a[i] for i in range(1,len(a)) if a[i] > a[i-1]]
# [5, 3, 2, 3, 3]
1
陈敏华 25 feb. 2018 a las 08:20