ジェネレーター/イテレーターを介してアクセスする大量のデータがあります。データセットの処理中に、そのデータセット内のいずれかのレコードに、処理中の現在のレコードの属性と同じ値を持つ属性があるかどうかを判断する必要があります。これを行う 1 つの方法は、ネストされた for ループを使用することです。たとえば、学生のデータベースを処理する場合、次のようなことができます。
def fillStudentList():
# TODO: Add some code here to filll
# a student list
pass
students = fillStudentList()
sameLastNames = list()
for student1 in students1:
students2 = fillStudentList()
for student2 in students2:
if student1.lastName == student2.lastName:
sameLastNames.append((student1, student2))
上記のコード スニペットはかなり改善される可能性があります。このスニペットの目的は、ネストされた for ループ パターンを示すことです。
ここで、クラス Student、イテレータであるクラス Students、およびメモリ効率の良い方法 (別のイテレータなど) でデータへのアクセスを提供するクラス Source があるとしましょう...
以下に、このコードがどのように見えるかをスケッチしました。この実装を改善する方法についてアイデアを持っている人はいますか? 目標は、フィルター処理されたセットを処理できるように、同じ属性を持つ非常に大きなデータセット内のレコードを検索できるようにすることです。
#!/usr/bin/python
from itertools import ifilter
class Student(object):
"""
A class that represents the first name, last name, and
grade of a student.
"""
def __init__(self, firstName, lastName, grade='K'):
"""
Initializes a Student object
"""
self.firstName = firstName
self.lastName = lastName
self.grade = grade
class Students(object):
"""
An iterator for a collection of students
"""
def __init__(self, source):
"""
"""
self._source = source
self._source_iter = source.get_iter()
self._reset = False
def __iter__(self):
return self
def next(self):
try:
if self._reset:
self._source_iter = self._source.get_iter()
self._reset = False
return self._source_iter.next()
except StopIteration:
self._reset = True
raise StopIteration
def select(self, attr, val):
"""
Return all of the Students with a given
attribute
"""
#select_iter = self._source.get_iter()
select_iter = self._source.filter(attr, val)
for selection in select_iter:
# if (getattr(selection, attr) == val):
# yield selection
yield(selection)
class Source(object):
"""
A source of data that can provide an iterator to
all of the data or provide an iterator to the
data based on some attribute
"""
def __init__(self, data):
self._data = data
def get_iter(self):
"""
Return an iterator to the data
"""
return iter(self._data)
def filter(self, attr, val):
"""
Return an iterator to the data filtered by some
attribute
"""
return ifilter(lambda rec: getattr(rec, attr) == val, self._data)
def test_it():
"""
"""
studentList = [Student("James","Smith","6"),
Student("Jill","Jones","6"),
Student("Bill","Deep","5"),
Student("Bill","Sun","5")]
source = Source(studentList)
students = Students(source)
for student in students:
print student.firstName
for same_names in students.select('firstName', student.firstName):
if same_names.lastName == student.lastName:
continue
else:
print " %s %s in grade %s has your same first name" % \
(same_names.firstName, same_names.lastName, same_names.grade)
if __name__ == '__main__':
test_it()