2011-04-13 2 views
3

fiddling (사전 포함) 이후에 필자는 n to n 조회를 허용하는 데이터 구조가 필요하다는 결론에 도달했습니다. 한 가지 예가 있습니다 : 한 코스는 여러 학생들이 방문 할 수 있으며 각 학생은 여러 코스를 방문 할 수 있습니다.파이썬에서`n to n` 관계에 무엇을 사용 하시겠습니까?

이것을 달성하기위한 가장 비범 한 방법은 무엇입니까? 이 사례에 머무르기 위해 500 명 이상의 학생과 100 과목이 될 것입니다. 그래서 나는 실제 데이터베이스 소프트웨어 사용을 피하고 싶습니다.

감사합니다.

+2

파이썬과 함께 패키지 된 sqlite3을 사용하는 것은 어떻습니까? 텍스트 파일을 사용하며 외부 라이브러리가 필요하지 않습니까? – GWW

+2

[Multimap] (http://en.wikipedia.org/wiki/Multimap)이라는 용어가 유용 할 것 같습니다. 일반적으로 단방향 인덱싱에만 사용됩니다. (또한 SQLite는 최고입니다 - SQL DDL/DQL은 SQL의 모든 한계에도 불구하고 여러 가지 관계형 질문을 간단하게 만들 수 있습니다.) –

답변

1

작업 세트가 작기 때문에 학생 ID를 Course 클래스의 목록으로 저장하는 것은 문제가되지 않는다고 생각합니다. 다른 방법이있다

studentIDToGet = "johnsmith001" 
studentsCourses = list() 
for course in courses: 
    if studentIDToGet in course.studentIDs: 
     studentsCourses.append(course.id) 

당신이 그것을 할 수 있습니다 : 수업 시간에 학생을 찾는 것은, 학생이에 코스를 찾을 단지 과정을 반복하고 ID를 찾으려면

course.studentIDs 

을하는 것처럼 간단 할 것 . courseIDs에 매핑 된 studentIDs 사전 하나 또는 두 개의 사전 - 하나의 매핑 된 studentID : courseIDs 및 another courseIDs : studentIDs -를 업데이트 할 때 서로 업데이트 할 수 있습니다.

코드를 작성한 코드는 아마도 가장 느릴 것입니다. 따라서 작업 세트가 충분히 작아서 문제가되지 않을 것이라고 언급 한 것입니다. 언급했지만 코드를 보여주지 않은 다른 암시는 노력을 기울일만한 가치가없는 코드를 만들어야합니다.

0

학생과 코스 모두 색인을 생성한다고 가정합니다. 그렇지 않으면 [St1, Crs1], (St1, Crs2) .. (St2, Crs1) ... (Sti, Crsi) ...]를 차례로 저장 한 튜플 목록을 쉽게 만들 수 있습니다. 필요할 때마다 선형 검색을 수행하십시오. 최대 500 명까지는 나쁘지 않습니다.

그러나 빠른 검색을 원하는 경우 기본 제공되는 데이터 구조가 없습니다. 2 개의 사전을 간단하게 사용할 수 있습니다 :

courses = { crs1: [ st1, st2, st3 ], crs2: [ st_i, st_j, st_k] ... } 
students = { st1: [ crs1, crs2, crs3 ], st2: [ crs_i, crs_j, crs_k] ... } 

주어진 학생의 경우, 지금 과목은 학생입니다. 주어진 코스 c에서 학생들을 찾는 것은 코스 [c]입니다.

0

원하는 것을 간단하게하기 위해 데이터 멤버 및 메서드를 사용하여 클래스를 유지 관리하고 유지 관리하는 간단한 클래스를 만들 수 있습니다. 이 문제에 대해 두 개의 사전이 필요할 것입니다. 학생 이름 (또는 ID)을 입력하여 각각의 과목을 추적하고, 다른 하나는 각 반마다 어떤 학생이 있는지 추적합니다.

defaultdicts 'collections'모듈에서 일반 dicts 대신 사용할 수 있습니다. 여기의 의미는 다음과 같습니다

실행은 다음과 같은 출력을 생성
from collections import defaultdict 

class Enrollment(object): 
    def __init__(self): 
     self.students = defaultdict(set) 
     self.courses = defaultdict(set) 

    def clear(self): 
     self.students.clear() 
     self.courses.clear() 

    def enroll(self, student, course): 
     if student not in self.courses[course]: 
      self.students[student].add(course) 
      self.courses[course].add(student) 

    def drop(self, course, student): 
     if student in self.courses[course]: 
      self.students[student].remove(course) 
      self.courses[course].remove(student) 
     # remove student if they are not taking any other courses 
     if len(self.students[student]) == 0: 
      del self.students[student] 

    def display_course_enrollments(self): 
     print "Class Enrollments:" 
     for course in self.courses: 
      print ' course:', course, 
      print ' ', [student for student in self.courses[course]] 

    def display_student_enrollments(self): 
     print "Student Enrollments:" 
     for student in self.students: 
      print ' student', student, 
      print ' ', [course for course in self.students[student]] 

if __name__=='__main__': 

    school = Enrollment() 

    school.enroll('john smith', 'biology 101') 
    school.enroll('mary brown', 'biology 101') 
    school.enroll('bob jones', 'calculus 202') 

    school.display_course_enrollments() 
    print 
    school.display_student_enrollments() 

    school.drop('biology 101', 'mary brown') 
    print 
    print 'After mary brown drops biology 101:' 
    print 
    school.display_course_enrollments() 
    print 
    school.display_student_enrollments() 

:

Class Enrollments: 
    course: calculus 202 ['bob jones'] 
    course: biology 101 ['mary brown', 'john smith'] 

Student Enrollments: 
    student bob jones ['calculus 202'] 
    student mary brown ['biology 101'] 
    student john smith ['biology 101'] 

After mary brown drops biology 101: 

Class Enrollments: 
    course: calculus 202 ['bob jones'] 
    course: biology 101 ['john smith'] 

Student Enrollments: 
    student bob jones ['calculus 202'] 
    student john smith ['biology 101'] 
1

그것은 당신이 구조를 신속하게 수행 할 수 있도록하려면 어떤 작업에 완전히 의존합니다.

코스와 학생과 관련된 속성을 빠르게 찾을 수 있기를 원한다면, 예를 들어 특정 코스에 대한 학습에 몇 시간을 소비했는지, 또는 코스에 어떤 학년이 있었는지 등 그는 그것을 완료, 그는 N 학생들의 수와 m이다 과목의 수이고, 당신이 필요 아마 등 N * m에게 요소를 포함하는 벡터를 완료합니다.

다른 한편으로 학생이 택한 평균 코스 수는 실제 코스 시나리오의 총 코스 수보다 훨씬 적으며 모든 코스를 빠르게 찾을 수 있기를 원합니다. 학생이 수강 한 과목에서리스트를 가질 수 있는지에 따라 n 개의리스트, 링크 된리스트, 크기를 재조정 할 수있는 벡터 또는 유사한 것으로 구성된 배열을 사용하고 싶을 것입니다. 목록 중간에있는 요소를 빠르게 제거하거나 임의의 위치에있는 요소에 빠르게 액세스 할 수 있습니다. 둘 다 목록 중간에있는 요소를 신속하게 제거하고 목록 요소에 빠르게 임의 액세스 할 수 있기를 원한다면 어떤 종류의 트리 구조가 가장 적합 할 수 있습니다.

대부분의 트리 데이터 구조는 모든 기본 연산을 트리의 요소 수와 로그 시간으로 수행합니다. 무작위로 구성된 트리의 평균 시간이 로그 일지라도 일부 트리 데이터 구조에는 트리의 요소 수에 선형 인 이러한 연산자에 상각 된 시간이 있습니다. 이런 경우가 발생하는 전형적인 예는 바이너리 검색 트리를 사용하고 점차 커질수록 더 큰 요소로 구성하는 경우입니다. 그렇게하지 마라. 이 경우 트리를 작성하기 전에 요소를 스크램블하거나 분할 및 정복 방법을 사용하여 목록을 두 부분과 하나의 피벗 요소로 분할하고 피벗 요소로 트리 루트를 만든 다음 재귀 적으로 트리를 만듭니다. 목록의 왼쪽 부분과 목록의 오른쪽 부분에서 나누기 및 정복 방법을 사용하고 왼쪽 자식과 오른쪽 자식으로 각각 루트에 첨부합니다.

죄송합니다. 저는 파이썬을 모르므로 언어의 일부분이며 사용자가 직접 만들어야하는 데이터 구조를 알지 못합니다.

관련 문제