Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 6, 2009 22:02:14

guest01
От:
Зарегистрирован: 2007-03-24
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

Привет,

Есть некоторое консольное приложение с множеством ключей. Нужно перебрать все параметры и создать список уникальных командных строчек. Пусть есть словарь “имя ключа”:. Например:

par = {
‘-q’ : ,
‘-w’ : ,
‘-e’ : ,
‘-r’ : ,
‘-f’ : ,
‘-t’ : ,
‘-d’ : ,
}

Хочется узнать способ как получить этот набор уникальных команд не путем кучей forов, а более изящно. Возможно функциональное программирование здесь можно применить.



Офлайн

#2 Окт. 6, 2009 22:34:52

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

А чем optparse не угодил?



Офлайн

#3 Окт. 6, 2009 22:40:56

guest01
От:
Зарегистрирован: 2007-03-24
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

Это совсем про другое. Мне в скрипте нужно сгенерировать различные комбинации. А не парсить командную строку для скрипта



Офлайн

#4 Окт. 6, 2009 22:54:51

guest01
От:
Зарегистрирован: 2007-03-24
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

Пока есть только решение с кучей for.

v = par.values()

for x,y,z,m,n,k,l,f in [(x,y,z,m,n,k,l,f ) for x in v for y in v for z in v for m in v for n in v for k in v for l in v for f in v]:
print x + “ ” + y + “ ” + z + “ ” + m + “ ” + n + “ ” + k + “ ” + l + “ ” + f

Но оно мне не нравится, так как у меня параметров аж 16.



Офлайн

#5 Окт. 6, 2009 23:12:25

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Перебор ключей консольного приложения

itertools.permutations, itertools.product



Офлайн

#6 Окт. 7, 2009 02:57:44

guest01
От:
Зарегистрирован: 2007-03-24
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

http://code.activestate.com/recipes/502199/
Отсюда взял генератор. Одно плохо, полный перебор дает миллиарды комбинаций :) Питон не выдерживает и вылетает с MemoryError.



Офлайн

#7 Окт. 7, 2009 05:22:56

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

Офлайн

#8 Окт. 7, 2009 13:28:33

guest01
От:
Зарегистрирован: 2007-03-24
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

А какая разница? ) Там такая вложенность будет и думаю также по памяти обвалится.



Офлайн

#9 Окт. 7, 2009 16:44:24

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Перебор ключей консольного приложения

guest01
http://code.activestate.com/recipes/502199/
Отсюда взял генератор. Одно плохо, полный перебор дает миллиарды комбинаций :) Питон не выдерживает и вылетает с MemoryError.
Вы наверное не генератор взяли, а первую версию, которая не ленивая. Генераторы по определению не могут так себя вести.
Не уверен, что это именно то, что нужно, но может хоть как-то поможет или натолкнет на решение:
import operator

def comb(*sequences):
lengths = [len(seq) for seq in sequences]
range_len_seq = range(len(sequences))
max_count = reduce(operator.mul, lengths)
_tmp = lengths + [1] # append multiplicative identity
dividers = [reduce(operator.mul, _tmp[-x-1:]) for x in range_len_seq][::-1]
modulos = lengths
for n in range(max_count):
yield [sequences[r][(n/dividers[r])%modulos[r]] for r in range_len_seq]

par = {
'-q' : ['0', '1', '2', '3', '4'],
'-w' : ['0', '1'],
'-e' : ['2', '3'],
'-r' : ['1', '2'],
'-f' : ['1 ', '2'],
'-t' : ['1', '2', '4', '8'],
'-d' : ['1', '2', '3', '4', '5', '6'],
}

groupped = [["%s%s" % (key, val) for val in vals] for key,vals in par.iteritems()]

for combination in comb(*groupped):
print combination
Поскольку оно ленивое, то количество комбинаций ему по барабану. Ваш пример породил не миллиарды, а гораздо меньше, но съест оно любое вразумительное количество:
$ time python test.py  |wc -l
1920

real 0m0.042s
user 0m0.032s
sys 0m0.004s



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version