Найти - Пользователи
Полная версия: Прерывание цыкла генератора
Начало » Python для экспертов » Прерывание цыкла генератора
1 2 3 4
agryn
Есть очень большой (или просто большой) /etc/passwd файл, нужно из него очень быстро извлечь username по uid.
Быстро читать конечно нужно с помощью генератора. Но если например запись с самого начала то не оптимально далее дочитывать строки. От сюда вопрос как можно после получения первого значения прекратить/прервать генератор (по аналогии как это делается breack в простом цикле)?
def get_usrname(user_uid):
    passwd_file = open('/etc/passwd')
    user_name_list = [passwd_file_line.split(':')[0] for passwd_file_line in passwd_file if passwd_file_line.split(':')[2] == user_uid]
    return user_name_list[0]
"""
## example /etc/passwd
psaftp:x:505:506:anonftp psa user:/:/sbin/nologin
apache:x:506:507:Apache server:/:/sbin/nologin
drweb:x:100:511:DrWeb system account:/var/drweb:/bin/false
webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin
mailman:x:41:41:GNU Mailing List Manager:/usr/lib/mailman:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
named:x:25:25:Named:/var/named:/sbin/nologin
sw-cp-server:x:507:512::/:/bin/true
paveln:x:10000:509::/var/www/vhosts/localhost.localdomain:/bin/false
nginx:x:498:497:Nginx user:/var/lib/nginx:/bin/false
test3:x:10001:10001::/home/test3:/bin/bash
test4:x:10002:10002::/home/test4:/bin/bash
testuser:x:10003:10003::/home/testuser:/bin/bash
testuser1:x:10003:10004::/home/testuser:/bin/bash
"""
Rodegast
Я так и не понял в чём у тебя проблема?
def get_usrname(user_uid):
	for x in open('/home/rodegast/pass'):
		if x.split(':')[2] == user_uid:
			return x.split(':')[0]
print get_usrname("505")
Или как то так отфильтровать можно:
user_uid = "506"
print map(lambda x: x.split(':')[0], filter(lambda x:x.split(':')[2] == user_uid, open('/home/rodegast/pass')))
agryn
Rodegast
def get_usrname(user_uid):
	for x in open('/home/rodegast/pass'):
		if x.split(':')[2] == user_uid:
			return x.split(':')[0]
Вот этот код нужно с помощью генератора для большой скорости.
PooH
agryn
Вот этот код нужно с помощью генератора для большой скорости.
Не знаю уж, какой скорости вы хотите добиться на сотне строк файла паролей. Но вам дали правильные вариант - файл читается построчно, до первого включения, а у вас как раз весь считывается в список :P
ну или, если хотите, в более функциональном стиле:
def first(ls, test):
    for x in ls:
        if test(x):
            return x
def get_username(search_uid):
    with open('/etc/passwd') as inf:
        return first((passwd_file_line.split(':') for passwd_file_line in inf), lambda x: x[0] == search_uid)
Budulianin
agryn
Вообще-то генератор списков это просто “синтаксический сахар” и по реализации ничем не отличается, от обычного for. Следовательно он работает с такой же скоростью.

lst = []
for elem in xrange(10):
    lst.append(elem)

тоже самое
lst = [elem for elem in xrange(10)]

Или генератор списков это выражение генератор преобразованный в список при помощи list ?
smoke853
может вместо return использовать yield ? Может автор темы эту быстроту имеет ввиду?
http://savepic.ru/4976932.jpg
Budulianin
smoke853
может вместо return использовать yield ? Может автор темы эту быстроту имеет ввиду?

Какая от этого скорость? Так только памяти меньше ест
sergeek
comprehension'ы оптимизируют как раз-таки полную генерацию списка и было бы грубо требовать от них наличие break'а.
Раз уж фп-тред
import operator as op
 
split = lambda sep : lambda string : string.split(sep)
 
def find(item, seq, test=op.eq, key=lambda elt : elt):
    for elt in seq:
        if test(item, key(elt)):
            return elt
            
def get_username(uid):
    return find(uid,
                map(split(':'),
                    open('/etc/passwd')),
                key=op.itemgetter(2))[0]
 
print(get_username('10'))

smoke853
В смысле какая скорость? в первом случае время выполнения = 0.755, во втором = 0.002, очевидно что второй вариант работает быстрее.
flip89
smoke853
В смысле какая скорость? в первом случае время выполнения = 0.755, во втором = 0.002, очевидно что второй вариант работает быстрее.
Долго думал, где же подвох)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB