$ wc -l /etc/passwdTrong python, các nhanh nhất để làm việc này là:
86 /etc/passwd
(hãy tự trả lời trước khi xem đáp án)
In [1]: sum(1 for line in open('/etc/passwd'))Giải thích
Out[1]: 86
sum - tính tổng của một chuỗi các số.
open('/etc/passwd') - mở file /etc/passwd và trả về một file object. File object cũng là iterator object, nó implement 2 method theo iterator protocol:
In [4]: f = open('/etc/passwd')
In [8]: hasattr(f, '__iter__')
Out[8]: True
In [9]: hasattr(f, 'next')
Out[9]: True
Nói đơn giản, bất cứ object nào có CẢ 2 method __iter__ và next thì nó đã implement iterator protocol và object đấy có thể dùng như 1 iterator. Khi một object (f) là 1 iterator thì có thể viết:
for x in f:để duyệt qua các phần tử mà f sẽ trả về.
Với file object, nó trả về lần lượt từng dòng trong file.
1 for line in open('/etc/passwd') - sẽ trả về một list toàn số 1, số các số 1 bằng số dòng trong file /etc/passwd.
Nên tổng của list này chính là số dòng trong file.
Bonus
đếm số dòng của tất cả các file có extension là ".py" trong một thư mục:
def count(dest='.', ftype='.py'):
no_files = 0
locs = 0
def filenames():
for d, _, fns in os.walk(dest):
for fn in fns:
yield os.path.join(d, fn)
for fn in filenames():
no_files += 1
fd = open(fn)
loc = sum(1 for line in fd)
print '%5d %s' % (loc, fn)
locs += loc
fd.close() # đóng file sau khi dùng xong để tránh leak file descriptor, có thể dùng with open(fn) để tự động làm việc này
print 'Total of files:', no_files
print 'Total of lines:', locs
Credit:
http://stackoverflow.com/questions/845058/how-to-get-line-count-cheaply-in-python
In [1]: sum(1 for line in open('/etc/passwd'))
ReplyDelete=> đơn giản nhưng không phải thằng nào cũng nghĩ ra (y)
Thanks