Это также зависит от того, как Ваш алгоритм лицензии работает. Я предложил бы, чтобы Вы изучили использование чего-то как Diffie†“обмен ключа Hellman (или даже RSA) для генерации своего рода общественности/закрытого ключа, которая может быть передана пользователям, на основе некоторой информации.
(В зависимости от приложения, я знаю об одном случае, где я записал код лицензии контракта для компании, они использовали MAC-адрес и некоторые другие данные, хешировали его и зашифровали хеш, дав им "значение ключа", если регистрационный номер был корректен). Это гарантирует, что файл ключей не может быть перемещен, (или дан) к другой машине, таким образом 'крадя' программное обеспечение.
, Если Вы хотите вырыть глубже и избежать хакеров, это - целое 'nother тема....
class Bob
end
def create(name)
return eval("#{name}.new")
end
b = create(:Bob)
puts b.class
Когда известно, что нужно удалить ровно один элемент, его можно найти и удалить еще быстрее:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(99)]; import random" "thelist=list(lod); random.shuffle(thelist); where=(i for i,d in enumerate(thelist) if d.get('id')==2).next(); del thelist[where]"
10000 loops, best of 3: 72.8 usec per loop
(используйте встроенную функцию next
вместо .next
, если вы, конечно, используете Python 2.6 или выше) - но этот код не работает, если количество dicts, удовлетворяющих условию удаления, не равно единице. Обобщая это, мы имеем:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*3; import random" "thelist=list(lod); where=[i for i,d in enumerate(thelist) if d.get('id')==2]; where.reverse()" "for i in where: del thelist[i]"
10000 loops, best of 3: 23.7 usec per loop
где перетасовка может быть удалена, потому что, как мы знаем, уже есть три слова с равным интервалом, которые нужно удалить. И listcomp, без изменений, работает хорошо:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*3; import random" "thelist=list(lod); thelist[:] = [d for d in thelist if d.get('id') != 2]"
10000 loops, best of 3: 23.8 usec per loop
целиком и полностью, с удалением всего 3 элементов из 99. При более длинных списках и большем количестве повторений это, конечно, еще больше:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*133; import random" "thelist=list(lod); where=[i for i,d in enumerate(thelist) if d.get('id')==2]; where.reverse()" "for i in where: del thelist[i]"
1000 loops, best of 3: 1.11 msec per loop
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*133; import random" "thelist=list(lod); thelist[:] = [d for d in thelist if d.get('id') != 2]"
1000 loops, best of 3: 998 usec per loop
В общем, очевидно, не стоит использовать тонкости создания и изменения списка индексов для удаления, против совершенно простого и очевидного понимания списка, чтобы, возможно, получить 100 наносекунд в одном маленьком случае и потерять 113 микросекунд в более крупном ;-). Избегание или критика простых, понятных и совершенно адекватных по производительности решений (например, составления списков для этого общего класса задач «удалить некоторые элементы из списка») - особенно неприятный пример хорошо известного тезиса Кнута и Хоара о том, что «преждевременная оптимизация - это корень всего зла в программировании »! -)
Вы можете попробовать следующее:
a = [{'id': 1, 'name': 'paul'},
{'id': 2, 'name': 'john'}]
for e in range(len(a) - 1, -1, -1):
if a[e]['id'] == 2:
a.pop(e)
Если вы не можете открывать с начала - открывать с конца, это не нарушит цикл for.
Вот способ сделать это с пониманием списка (при условии, что вы назвали свой список 'foo'):
[x for x in foo if not (2 == x.get('id'))]
Substitute 'john' == x.get ('name' )
или что-то еще.
filter
также работает:
foo.filter (lambda x: x.get ('id')! = 2, foo)
И если вы хотите генератор, который вы можете использовать itertools:
itertools.ifilter (lambda x: x.get ('id')! = 2, foo)
Однако, начиная с Python 3, filter
будет возвращать в любом случае итератор, так что, как предположил Алекс, составление списка действительно лучший выбор.
Вы можете попробовать что-то вроде следующих строк:
def destructively_remove_if(predicate, list):
for k in xrange(len(list)):
if predicate(list[k]):
del list[k]
break
return list
list = [
{ 'id': 1, 'name': 'John' },
{ 'id': 2, 'name': 'Karl' },
{ 'id': 3, 'name': 'Desdemona' }
]
print "Before:", list
destructively_remove_if(lambda p: p["id"] == 2, list)
print "After:", list
Если вы не создадите что-то вроде индекса по вашим данным, я не думайте, что вы можете добиться большего успеха, чем "перебор" таблицы сканировать "по всему списку. Если ваши данные отсортированы по ключу, вы можете использовать модуль bisect для найти нужный объект несколько быстрее.
# assume ls contains your list
for i in range(len(ls)):
if ls[i]['id'] == 2:
del ls[i]
break
Вероятно, будет быстрее, чем методы понимания списка в среднем, потому что он не просматривает весь список, если находит рассматриваемый элемент на ранней стадии.
Это не совсем ответ (поскольку я думаю, у вас уже есть неплохие из них), но ... думали ли вы о том, чтобы иметь словарь
вместо списка словарей?