2015-02-06 3 views
2

У меня было собеседование сегодня. Во время этого меня попросили записать алгоритм, который изменит список. Во-первых, я предложил ответ, используя обратную() метод:Альтернативный список Python Требуется обратное решение

x = [1,2,3,4,5] 
    y = reversed(x) 
    for i in y: 
     print i 

Старший разработчик проводит интервью спросил меня, если я знаю другой путь, на котором я записал другой известный метод с нарезку:

x = [1,2,3,4,5] 
    y = x[::-1] 

К сожалению, он тоже был недоволен этим решением и попросил меня подумать о другом. Через несколько минут я сказал, что не могу найти лучшего. Он сказал, что это недостаточно для их стандартов.

У меня все в порядке со своим мнением и у меня нет проблем с практикой в ​​моем коде. Мой вопрос: какое лучшее решение я не знаю, если оно есть. Может быть, есть еще какой-то еще «программист» ... Только другое, что приходит в голову - это рекурсия, однако я думал об этом только после того, как интервью уже было сделано. Спасибо.

+11

Я полагаю, он искал вас, чтобы предложить вам алгоритм, а не готовые (и правильные!) Методы Python. – CoryKramer

+1

Вы спросили его, что он искал? – AlG

+0

похоже, что это было так, я не думал о коробке.Это было мое первое интервью для такого рода позиций. Я слишком нервничал и думал, насколько глупым я был вместо того, чтобы просить его разъяснить. – bullettrain

ответ

4

Оба ваши ответы хороши с точки зрения питона так интервьюер должен был просить вас реализовать свой собственный метод:

Использование рекурсии:

def recur_rev(l): 
    return recur_rev(l[1:]) + l[:1] if l else l 

или список Комп и диапазон, начиная с длина л -1 и идет в обратном направлении:

l = list(range(100)) 

print([l[ind] for ind in range(len(l)-1,-1,-1)]) 

Использование itertools.count:

from itertools import count 
cn = count(len(l) -1, -1) 

print([l[next(cn)] for ele in l]) 

Для повышения эффективности использования выражения генератора:

rev = (l[next(cn)] for ele in l) 

for ele in rev: 
    print(ele) 

Или с помощью карты:

print(list(map(l.__getitem__,range(len(l)-1,-1,-1)))) # list needed for python3 

[99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 

без вызова списка на карте, мы получим объект на карту, мы можем перебирать в Python3, вы может использовать itertools.imap в python2 для достижения аналогичного результата

+2

интересный ответ. Спасибо. Наверное, я думал о том, чтобы дать самый пифонический ответ вместо того, чтобы придумать свое решение. – bullettrain

+2

@ user44772, как я уже сказал в терминах python, ваши ответы хороши, особенно используя обратную с точки зрения эффективности, поэтому единственным реальным логическим объяснением является интервьюер, который хотел бы, чтобы вы придумали альтернативные не встроенные методы. –

+0

Первые 2 - разные подходы. Остальным интересно посмотреть, но почти то же самое, я думаю, что единственные другие подходы - это замена элементов списка или их удаление – jamylak

2

Один простой алгоритм, который можно легко портировать на другие языки:

x = [1,2,3,4,5] 
y = [] 
for i in len(x): 
    y.append(x[len(x) - 1 - i]) 

Или с помощью итератора. Это может быть легко перенесено для использования с прикованным списком, где вы не знаете, длину:

x = [1,2,3,4,5] 
y = [] 
x_iterator = iter(x) 
try: 
    while (1): 
    y.insert(0, x_iterator.next()) 
except: 
    print y 

Или более вещую версию с вкладышем:

x = [1,2,3,4,5] 
y = [] 
for elem in x: 
    y.insert(0, elem) 
+0

Да, понимание списка, но я заменил этот пример, это было плохо. –

2

Я предполагаю, что ваш интервьюер Бесполезный Не хотите, чтобы вы использовали встроенные методы Python, но алгоритм, который является более языковым агностиком.Что-то вроде:

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

while len(lst) > 0: 
    lst2.append(lst.pop()) 

или

lst2 = [lst.pop() for _ in lst[:]] 
+0

Очень возможно, что он хотел чего-то подобного, однако в этот момент я немного нервничал, и было также необычно писать на листе бумаги без помощи онлайн. Однако это хороший урок для некоторых будущих интервью. Спасибо Адаму. – bullettrain

+0

'while len (lst)> 0' можно заменить на' while lst' – jamylak

2

Я предполагаю, что ваш интервьюер хотел услышать что-то вроде этого:

Несложный способ вернуть список, чтобы узнать его длину, то итерацию от len-1 до 0 и добавьте i-й элемент к результату. Этот подход отлично работает с реальными списками, но как мы можем вернуть генератор, т. Е. Что-то, чья длина неизвестна и не может быть найдена? (Хорошие pythonistas используют генераторы и дают вместо списков и возвратов).

Здесь мы нуждаемся в структуре данных, известной как «стек». Стек подобна, ну, стопку вещей, например пластин, накладываются друг на друга.

Все, что вы положили последний выходит первого, независимо был поставлен первого выходит последнего. Таким образом, наша стратегия будет выглядеть следующим образом:

  • в то время как есть элементы, поместить каждый элемент в стек
  • пока стек не пуст, всплывающие элементы из стека и вернуть их

Стеки могут быть запрограммированы в питоне с использованием списков, где .append помещает элемент на вершине стека, и .pop удаляет последнюю вещь из стека:

def reverse(it): 
    stack = [] 
    for item in it: 
     stack.append(item) 
    while stack: 
     yield stack.pop() 

Конечно, у Python уже есть встроенный стек, и это стек из кадров вызова. Мы можем использовать это вместо моделируемых один выше, что приводит нас к следующему рекурсивной решения:

def reverse(it): 
    head = next(it) 
    for item in reverse(it): 
     yield item 
    yield head 

в Python3, это еще более элегантно:

def reverse(it): 
    head = next(it) 
    yield from reverse(it) 
    yield head 

Опять же, это работает с произвольные итерации, длина которых неизвестна во время вызова.

2

Как о чем-то вроде этого:

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

for i in xrange(len(x)/2): 
    x[i], x[-i - 1] = x[-i - 1], x[i] 

print(x) 

Идея заключается в том, чтобы поменять местами элементы массива с противоположных направлений

+0

Мне нравится xrange(). Это сделало бы интервьюера следующим вопросом: range() vs xrange(). – adamo

1

Мне нравится этот путь:

def reverse(arr): 
    for i in range(len(arr)/2): 
     arr[-i-1], arr[i] = arr[i], arr[-i-1] 

В основном итерация через первую половину массив и свопинг i и len(i)-i-1.

Смежные вопросы