$ 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