2013-05-23 3 views
3

Вот моя первая программа на Python, маленькая утилита, которая преобразует из восьмеричного кода Unix для прав доступа к файлам в символической форме:Как упростить обработку списка в Python?

s=raw_input("Octal? "); 
digits=[int(s[0]),int(s[1]),int(s[2])]; 
lookup=['','x','w','wx','r','rx','rw','rwx']; 
uout='u='+lookup[digits[0]]; 
gout='g='+lookup[digits[1]]; 
oout='o='+lookup[digits[2]]; 
print(uout+','+gout+','+oout); 

Есть ли способы сократить этот код, воспользоваться каким-то «обработкой списка «? Например, чтобы сразу применить функцию int ко всем трем символам s без необходимости явной индексации. И индексировать в lookup используя весь список digits сразу?

+2

Вы намеренно хотите использовать ';' в конце каждой строки в этом скрипте? Это * Python *, [в конце концов] (http://stackoverflow.com/a/8236402/1167750) ... :) – summea

+2

Полностью для удовольствия (не используйте это), вот однострочный: ' print (','. join (c + '=' + ''. join ('xw r' [i-1: i & b] для i в (4,2,1)) для c, b в zip ('ugo' , map (int, raw_input («Octal?»))))) ' –

ответ

5

Вот немного оптимизированная версия кода:

s = raw_input("Octal? ") 
digits = map(int, s) 
lookup = ['','x','w','wx','r','rx','rw','rwx'] 
perms = [lookup[d] for d in digits] 
rights = ['{}={}'.format(*x) for x in zip('ugo', perms)] 
print ','.join(rights) 
+0

Это просто научило меня больше о Python, чем о многих поисках в документах. (И, конечно, я достаточно нетерпелив, не желая проходить типичные утомительные вводные уроки, которые я видел.) – murray

+0

К сожалению, я не вижу части «u =» и т. Д., Когда я запускаю этот код в интерактивном режиме, используя Python 2.7. И то же самое, если я выполняю его как скрипт под Python 3.3, заменяя строку 'raw_input'' import sys', а затем 's = sys.argv [1]', а последняя строка - 'print (',' .join (перманент)) '. – murray

+0

@murray Извините, это должны быть 'права', а не' perms'. –

11
digits=[int(s[0]),int(s[1]),int(s[2])]; 

можно записать в виде:

digits = map(int,s) 

или:

digits = [ int(x) for x in s ] #list comprehension 

Как это выглядит, как вы могли бы использовать python3.x (или планируете использовать его в будущем на основе ваше использование функции, например, использование печати), вы можете выбрать для понимания списка, если вы не захотите копать дальше, и используйте zip, как показано одним из более поздних ответов.

+1

+1 для использования как [map] (http://docs.python.org/2/library/functions.html#map), так и [list Понимание] (http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions) – Andy

+2

OP использует 'raw_input', поэтому это 2.X – Blender

+0

@Blender - Хорошая точка. Я этого не замечал (я только что увидел функцию-заявление печати). – mgilson

1

Вот моя трещина на него (в том числе и «-» для недостающих разрешений):

lookup = { 
    0b000 : '---', 
    0b001 : '--x', 
    0b010 : '-w-', 
    0b011 : '-wx', 
    0b100 : 'r--', 
    0b101 : 'r-x', 
    0b110 : 'rw-', 
    0b111 : 'rwx' 
} 

s = raw_input('octal?: ') 
print(','.join(# using ',' as the delimiter 
       r + '=' + lookup[int(n, 8)] # the letter followed by the permissions 
       for n, r in zip(tuple(s), 'ugo'))) # for each number/ letter pair 
+1

+1, но я бы 'zip (s, 'ugo')' для краткости. –

+0

@LevLevitsky ah yes Конечно –

4

Вы также можете сделать это с битмаски :

masks = { 
    0b100: 'r', # 4 
    0b010: 'x', # 2 
    0b001: 'w' # 1 
} 

octal = raw_input('Octal? ') 
result = '-' 

for digit in octal[1:]: 
    for mask, letter in sorted(masks.items(), reverse=True): 
     if int(digit, 8) & mask: 
      result += letter 
     else: 
      result += '-' 

print result 
+0

Ум, вы полагаетесь на порядок 'masks.items()', который не определен. Вы не имеете в виду 'sorted (masks.items(), reverseed = True)'? –

+0

@ LauritzV.Thaulow: Да, спасибо. Это несколько предсказуемо в CPython. – Blender

2

Вот моя версия, вдохновленные решения в Blender:

bits = zip([4, 2, 1], "rwx") 
groups = "ugo" 

s = raw_input("Octal? "); 
digits = map(int, s) 

parts = [] 
for group, digit in zip(groups, digits): 
    letters = [letter for bit, letter in bits if digit & bit] 
    parts.append("{0}={1}".format(group, "".join(letters))) 

print ",".join(parts) 

Я думаю, что лучше не указывать в явном виде список lookup.

+0

«Шесть один, полдюжины других»? Terser code, если вы создаете список 'lookup' или более длинный код, но более длинный, чем ближе к духу того, как вычисления вычисляются с помощью манипуляций' bits'. Мне нравятся небольшие проблемы, которые настолько богаты возможными решениями. Спасибо всем участникам здесь. – murray

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