One. concept
When the program uses data structure to process data, how to organize and save the rose stone in memory? Please note that the data stored on disk as part of permanent storage (such as relational table) cannot be called data structure here. An algorithm is a set of instructions that process data for a specific purpose step by step. Therefore, the algorithm logically uses various data structures to solve specific computing problems.
Data structure is a basic concept of computer science. Here we learn about some common concepts of data structures and their relationship with some python data types. There are also python specific data structures that will become another category.
II. General data structure
1. Linear data structure (data structure that stores data elements in a sequential manner)
Array (index), linked list (link to another element and its data), stack( LIFO(Last in first out), FILO(fifo)) Queue( FIFO(fifo)), Matrix (two-dimensional data structure in which data elements are referenced by a pair of indexes)
2. Nonlinear data structure (there is no sequential connection of data elements in the data structure, any pair or group of data can be related to each other, and can be accessed without strict number order)
Binary tree::It is a data structure, and each data element can be connected to up to two other data elements, starting with a root node. Heap: This is a special case of tree data structure, in which the data in the parent node is strictly greater than/Equal to or strictly less than its children. Hash table: it is a data structure consisting of arrays associated with each other using hash functions. It uses keys instead of indexes of data elements to retrieve values Figure: it is a sort of fixed points and nodes, some of which are connected to each other through links
Python specific data structures
These data structures are unique to the python language. They can store different types of data more flexibly and process faster in the python environment.
List: it is similar to an array except that data elements can have different data types. You can include both numeric and string data in a Python list.
Tuples: tuples are similar to lists, but they are immutable, which means that the values in tuples cannot be modified, so they can only be read.
Dictionary: this dictionary contains key value pairs as its data elements.
3, Array (it is a container. Note that compared with the list in python, it can be declared in different languages. The index starts from 0. The array length and each element can be accessed through the index). It can accommodate a certain number of items. These items are of the same type. Most data structures use arrays to implement their algorithms.
1. Basic operation
Traversal, insert, delete, search, update
2. Implementation of array in Python language
from array import * #b/B/c/i/I/f/d #1-byte signed integer / 1-byte unsigned integer / 1-byte character / 2-byte signed integer / 2-byte unsigned integer / 4-byte floating point number / 8-byte floating point number arrayName=array('i',[10,20,30,40,50]) for i in arrayName: print(i) #Accessing array elements array1=arrayName print(array1[0]) print(array1[2]) #insert operation array1.insert(0,20) for i in array1: print(i) #Delete element array1.remove(40) #Find / search operation print(array1.index(20)) #If the value is no longer in the array, an error is returned #to update array1[0]=30
4, List (items in the list do not have to be of the same type) square brackets, and the index starts from 0
1. Access element: []
2. Update: you can update one or more elements of the list by giving slices to the left of the assignment operator, and you can add them to the elements in the list using the append() method
3. Delete element: del list1[2]
4. Repeat: *+
Lists respond to the + and * operators much like strings; they also mean concatenation and repetition, but it evaluates to a new list, not a string.
5, Yuanzu: () index starts from 0
1. Access element: [] slice
2. Change ancestor: tuples are immutable, which means that the value of tuple elements cannot be updated or changed. However, part of existing tuples can be created or reorganized into new tuples
3. Delete element: it is impossible to delete a single tuple element; delete the whole element - del tup
4. Basic operation of elements
6, Dictionary (each key and value are separated by colon, and each item is separated by (,); the whole dictionary data is enclosed in curly braces; if an empty dictionary is {}; the key is unique in the dictionary, and the value may not be unique. The value of the dictionary can be of any type, but the key must be of immutable type)
1. Access operation: [] if you try to access a data item using a key that does not belong to the dictionary, you will get an error
2. Update dictionary elements; (add - [])
3. Delete dictionary element: del (the dictionary no longer exists) dict.clear() clears the dictionary. The dictionary exists but is empty
Note: the key cannot have the same name. If the key has the same name, the latter will overwrite the previous one; the key must be immutable
7, Two dimensional array (it is an array of arrays. In this type of array, the position of data elements is referenced by two indexes instead of one index. It is a table containing row and column data, and each array element in the two-dimensional array is also an array)
from array import * T=[[1,2,3,4],[5,6,7,8],[9,12,13,14],[8,7,6,5]] #Two indexes are used to access the data elements in a two-dimensional array. One index refers to the main array or parent array, and the other index refers to the location of the data elements in the internal array #If only one index is used, Jiang Wei will print internal data at that index position print(T[0]) print(T[1][2]) #You can use the for loop to print the entire two-dimensional array, and use the end of the line to print the values in different lines for r in T: for c in r: print(c,end=" ") print() #Inserting values into a two-dimensional array T.insert(2,[0,5,11,13,6]) #Update the values in the two-dimensional array and use array index recopy to update the internal array or some specific data elements of the internal array T[2]=[11,9] T[0][3]=7 print('-------------------------------------------') for r in T: for i in r: print(i,end=' ') print() #Delete values from a 2D array del T[0][0] print('---------------------------------------') for r in T: for i in r: print(i,end=' ') print()
#Operation results F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py [1, 2, 3, 4] 7 1 2 3 4 5 6 7 8 9 12 13 14 8 7 6 5 ------------------------------------------- 1 2 3 7 5 6 7 8 11 9 9 12 13 14 8 7 6 5 --------------------------------------- 2 3 7 5 6 7 8 11 9 9 12 13 14 8 7 6 5
8, Collection (data items not in any particular order)
Elements in the collection cannot be duplicated.
The elements in the collection are immutable (cannot be modified), but the collection as a whole is mutable.
Any element attached to a python collection does not require an index. Therefore, the collection does not support any indexing or slicing operations
1. Create: Example
Days=set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
When you print a collection, the order of elements changes
2. Access the elements in the collection
You cannot access a single element of a collection. You can only access multiple elements, but you can print a list of individual elements by traversing
3. Add element (add)
4. Delete the element discard('element value ')
5. Joint operation of sets AllDays=DayA|DaysB a new set containing all different elements from the two sets
6. Intersection of sets
AllDays = DaysA & DaysB
7. Difference set
AllDays = DaysA - DaysB
#8. Comparison set
SubsetRes = DaysA <= DaysB SupersetRes = DaysB >= DaysA
9, Matrix
from array import * T = [[11, 12, 5, 2], [15, 6,10], [10, 8, 12, 5], [12,15,8,6]] print(type(T)) array1=array('b', [15, 6,10]) print(type(array1)) import numpy as np shuzu=np.arange(20) x=shuzu.reshape(5,4) print(x) print('--------------------------------------------------') print(np.mean(x,axis=1))#1 representative bank #delete print('Delete the second column:') print(np.delete(x,1,axis=1))#The element with index 1 of all rows and the element of the first column print(x[1][2]) ''' Access mode List:[][] Array:[][] Matrix:[][] '''
Ten. python node
In some cases, the memory allocation for storing data cannot be located in consecutive memory blocks. Therefore, with the help of pointers, the data and the address of the next position of the data element are also stored. Therefore, the address of the next data element is known from the value of the current data element. Usually such a structure is called a pointer. But in Python, they are called nodes.
Nodes are the basis for the processing of various other data structures, linked lists and trees in python
class daynames: def __init__(self,dataval=None): self.dataval=dataval self.nextval=None e1=daynames('Mon') e2=daynames('Tue') e3=daynames('Wed') e1.nextval=e3 e3.nextval=e2
2. Traversal of node elements
class daynames: def __init__(self, dataval=None): self.dataval = dataval self.nextval = None e1 = daynames('Mon') e2 = daynames('Tue') e3 = daynames('Wed') e1.nextval = e3 e3.nextval = e2 thisvalue=e1 while thisvalue: print(thisvalue.dataval) thisvalue=thisvalue.nextval
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py Mon Wed Tue Process finished with exit code 0
Eleven. python linked list (single linked list)
1. Create linked list
#establish class Node: def __init__(self,dataval=None): self.dataval=dataval self.nextval=None class SLinkedList: def __init__(self): self.headval=None #Traversal method def listprint(self): printval=self.headval while printval is not None: print(printval.dataval) printval =printval.nextval #Insert at the beginning of the list def AtBegining(self,newdata): NewNode = Node(newdata) NewNode.nextval = self.headval self.headval=NewNode #Inserts a node at the end of the list def AtEnd(self,newdata): NewNode = Node(newdata) if self.headval is None: self.headval=NewNode return laste=self.headval #I think this is the essence. while(laste.nextval): laste=laste.nextval laste.nextval=NewNode def Inbetween(self,middle_node,newdata): if middle_node is None: print("the mentioned node is absent") return NewNode = Node(newdata) NewNode.nextval=middle_node.nextval middle_node.nextval = NewNode list1=SLinkedList() list1.headval=Node('Mon') e2=Node('heTue') e3=Node('Wed') list1.headval.nextval=e2 e2.nextval=e3 #ergodic list1.listprint() #Insert node in header list1.AtBegining("sum") print('--------------------------') list1.listprint() print('-------------------------------------------') #Insert node at tail list1.AtEnd('Thu') list1.listprint() print('-----------------------------------') #Insert in the middle list1.Inbetween(e2,"Fri") list1.listprint()
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py Mon heTue Wed -------------------------- sum Mon heTue Wed ------------------------------------------- sum Mon heTue Wed Thu ----------------------------------- sum Mon heTue Fri Wed Thu
2. Delete elements from the linked list
#Delete a node from the linked list
#You can use the key of the node to delete a node. In the following program, find the previous node of the node to be deleted, and then point the next pointer of the node to the next node of the node to be deleted
class Node: def __init__(self, data=None): self.data = data self.next = None class SLinkedList: def __init__(self): self.head = None def Atbegining(self, data_in): NewNode = Node(data_in) #Key points NewNode.next = self.head self.head = NewNode #Function to remove node #What happens to be deleted is the first one def RemoveNode(self, Removekey): headVal = self.head if (headVal is not None): if(headVal.data == Removekey): self.head = headVal.next headVal = None return #Not the first case while(headVal is not None): if headVal.data == Removekey: break prev = headVal headVal = headVal.next if (headVal == None): return #After finding which node, the next node of the previous node points to the next node to be deleted, and the value of the node to be deleted is null prev.next = headVal.next headVal = None def LListprint(self): printval = self.head while (printval): print(printval.data), printval = printval.next list1=SLinkedList() list1.Atbegining('Mon') list1.Atbegining('Tue') list1.Atbegining('Wed') list1.Atbegining('The') list1.RemoveNode('Tue') list1.LListprint()
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py The Wed Mon Process finished with exit code 0
Twelve. Pile (enter from that end and exit from that end)
Indicates that the object is placed on another object, and the way of allocating memory in this data structure is the same. It stores array elements in a similar way, similar to piles of plates in the kitchen, one on top of the other, so the end of the stack data structure that allows operations can be called the top of the stack, and elements can be added to the top of the stack or only removed from the stack.
The last element in order in the stack will appear first because it can only be removed from the top of the stack. This operation is called last in first out. The operations of adding and deleting elements are called PUSH and POP. In the following program, we implement them as add and remove functions. First declare an empty list and use the append() and pop() methods to add and remove data elements.
class Stack: def __init__(self): self.stack = [] # add to def add(self, dataval): if dataval not in self.stack: #Add from the tail, and then add the latter one self.stack.append(dataval) return True else: return False #Delete, LIFO def remove(self): if len(self.stack) <=0: return ('no slement in the stack') else: return self.stack.pop() def peek(self): return self.stack[0] Astack = Stack() Astack.add("Mon") Astack.add("Tur") print(Astack.peek()) Astack.add('Wed') Astack.add('The') print(Astack.remove())
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py Mon The Process finished with exit code 0
Twelve. Queue (in from one end and out from the other)
I am familiar with queuing in daily life. Queue structure also means that data elements are arranged in a queue. The uniqueness of a queue depends on how items are added and deleted. These objects can be placed last but removed from the other end, so this is a first in, first out method. Queues can be implemented using python list, and elements can be added and removed using insert() and pop() methods. They are not inserted because data elements are always added at the end of the queue.
class Queue: def __init__(self): self.queue = list() def addtop(self,dataval): if dataval not in self.queue: self.queue.insert(0,dataval) return True return False def removefromq(self): if len(self.queue) > 0: return self.queue.pop() return ('No element in Queue!') def size(self): return len(self.queue) TheQueue = Queue() TheQueue.addtop("Mon") TheQueue.addtop("Tue") TheQueue.addtop("Wed") print(TheQueue.size()) print(TheQueue.removefromq()) print(TheQueue.removefromq())
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py 3 Mon Tue Process finished with exit code 0
Thirteen. python double ended queue
Double ended queues (or double ended queues) have the ability to add and delete elements from either end. The Deque module is part of the collection library and has methods to add and delete elements that can be called directly with parameters. In the following program, you will import the collections module and declare a double ended queue. You don't need any classes to implement these methods directly using the built-in.
import collections #Create a deque DoubleEnded = collections.deque(["Mon","Tue","Wed"]) #append to the right print('Adding to the right:') DoubleEnded.append("Thu") print(DoubleEnded) #append to the left print('adding to the left') DoubleEnded.appendleft('Sun') print(DoubleEnded) #Remove from the right print("Removing from the right") DoubleEnded.pop() print(DoubleEnded) #Remove from the left print("Removing from the left:") DoubleEnded.popleft() print(DoubleEnded) #Reverse the dequeue print("reverse the deque:") DoubleEnded.reverse() print(DoubleEnded)
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py Adding to the right: deque(['Mon', 'Tue', 'Wed', 'Thu']) adding to the left deque(['Sun', 'Mon', 'Tue', 'Wed', 'Thu']) Removing from the right deque(['Sun', 'Mon', 'Tue', 'Wed']) Removing from the left: deque(['Mon', 'Tue', 'Wed']) reverse the deque: deque(['Wed', 'Tue', 'Mon']) Process finished with exit code 0
Fourteen. python advanced linked list (bidirectional linked list)
We see another list of links that can be moved forward and backward. This kind of linked list is called bidirectional linked list. The following are the characteristics of a two-way linked list.
1. The two-way linked list contains the first and last link elements
2. Each connection has a numeric field and two link fields called next and prev
3. Each link is linked with its next link
4. Each link is linked with the previous link
5. The last link marks the end of the list as empty
'''
To create a two-way linked list, we use the Node class to create a double linked list. Using the same method as in the single linked list,
However, in addition to the data that exists in the node, the header pointer and the next pointer will be used for proper allocation to create two links in each node.
'''
class Node: def __init__(self, data): self.data = data self.next = None self.prev = None class doubly_linked_list: def __init__(self): self.head = None #Adding data elements def push(self,NewVal): NewNode = Node(NewVal) NewNode.next = self.head if self.head is not None: self.head.prev=NewNode self.head = NewNode #define the insert method to insert the element def insert(self,prev_node,NewVal): if prev_node is None: return #Note that this link goes through 4 (1. The next node of the new node points to the next node of the previous node. 2. The next node of the previous node points to the new node. 3. The previous node of the new node points to the previous node. 4. The previous node of the next node of the previous node points to the new node) NewNode = Node(NewVal) NewNode.next = prev_node.next prev_node.next = NewNode NewNode.prev = prev_node if NewNode.next is not None: NewNode.next.prev = NewNode #define the append method to add element at the end def append(self, NewVal): NewNode = Node(NewVal) NewNode.next = None if self.head is None: NewNode.prev = None self.head = NewNode return last = self.head while (last.next is not None): last = last.next last.next = NewNode NewNode.prey = last #print the doubly linked list def listprint(self, node): while(node is not None): print(node.data) last = node node = node.next dlist=doubly_linked_list() dlist.push(12) dlist.push(8) dlist.push(62) dlist.listprint(dlist.head) dlist.insert(dlist.head.next.next,13) dlist.append('30') dlist.listprint(dlist.head)
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py 62 8 12 62 8 12 13 30 Process finished with exit code 0
Fifteen. Hashtable
Hash table (also known as hash table) is a data structure whose address or index value of data element is generated by hash function. This makes accessing data faster. Because the index value is the key of the data value. In other words, the hash table stores key value pairs, but the keys are born through the hash function. Therefore, the search and insert functions of data elements become faster, because the key value itself becomes the index of the array in which the data is stored.
In python, the dictionary data type represents the implementation of a hash table. The keys in the dictionary meet the following requirements
1. The key of the dictionary is hashable, that is, the hash function is generated through the hash function, which generates a unique result for each unique value provided to the hash function
2. The order of data elements in the dictionary is not fixed
Access value [] in dictionary
Update dictionary elements
Delete dictionary element del can delete a single dictionary element or clear all the contents of the dictionary. You can also delete the entire dictionary in one operation. To explicitly delete the entire dictionary, simply use the Del statement dict.clear()
Sixteen. Number of python searches
A binary search tree (BST) is a tree in which all nodes follow the following attribute - the key of the left child tree of a node is less than or equal to the key of its parent node. The key of the right subtree of a node is greater than that of its parent node. Therefore, BST divides all its subtrees into two parts, the subtree on the left and the subtree on the right
left_subtree (keys) ≤ node (key) ≤ right_subtree (keys)
'''
Searching for values in the B-tree searching for values in the tree involves comparing the input value with the value of the exit node.
Here, the node is traversed from left to right, and finally the parent node.
If the searched value does not match any exit value, the message not found is returned; otherwise, the message found is returned.
'''
class Node: def __init__(self,data): self.left = None self.right = None self.data = data #Insert method to create nodes def insert(self,data): if self.data: if data<self.data: if self.left is None: self.left = Node(data) else: self.left.insert(data) elif data > self.data: if self.right is None: self.right = Node(data) else: self.right.insert(data) else: self.data = data #findval method to compare the value with nodes def findval(self,lkpval): if lkpval < self.data: if self.left is None: return str(lkpval)+'not found' return self.left.findval(lkpval) elif lkpval > self.data: if self.right is None: return str(lkpval)+'not found' return self.right.findval(lkpval) else: print(str(self.data)+' is found') def PrintTree(self): if self.left: self.left.PrintTree() print(self.data) if self.right: self.right.PrintTree() root = Node(12) root.insert(6) root.insert(14) root.insert(3) print(root.findval(7)) print(root.findval(14))
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py 7not found 14 is found None Process finished with exit code 0
Seventeen. python heap
Heap is a special tree structure in which each parent node is less than or equal to its child nodes. Then it is called min heap. If each parent node is greater than or equal to its child nodes. It is called max heap. It is very useful to implement priority queue, in which queue items with higher weight have higher priority in processing.
1. Create a heap by using a library named heapq built in python. The library has the related functions of various operations on the heap data structure.
heapify converts a regular class table into a heap. In the result heap, the smallest element is pushed to index position 0, but the remaining elements are not necessarily sorted.
heappush this function adds an element to the heap without changing the current heap.
heappop this function returns the smallest data element
Heappreplace this function replaces the smallest data element with the new value provided in the function (delete the smallest, push forward the rest, and fill in the content to be replaced)
Create the heap by simply using the list of elements with the heapify function.
import heapq H=[21,1,45,78,3,5] #Create a heap heapq.heapify(H) print(H) #Insert heap '''Inserting data elements into the heap is always added at the last index. However, it can be applied again only when the value is the smallest heapify Function adds the newly added element to the first.''' heapq.heappush(H,8) print(H) #Remove from heap '''You can use this function to an element at the first index,''' heapq.heappop(H) print(H) #Replace heap '''heapreplace The function always deletes the smallest element in the stack and inserts a new incoming element where it has not been repaired in any order''' heapq.heapreplace(H,6) print(H)
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py [1, 3, 5, 78, 21, 45] [1, 3, 5, 78, 21, 45, 8] [3, 8, 5, 78, 21, 45] [5, 8, 6, 78, 21, 45]
Eighteen. chart
A graph is a graphical representation of a set of objects linked by links. Interconnected objects are represented by points called fixed points, and links connecting fixed points are called edges.
1. Basic operation
Show shape vertices
Show drawing edges
Add a vertex
Add edge
Create a graph
You can easily render diagrams using python dictionary data structure types. We represent vertices as dictionary keywords, and the links between vertices become boundaries as values in the dictionary
In the figure above
V= E= use python Implement this diagram #create the dictionary eith graph elements graph = { "a":["b","c"], "b":["a","d"], "c":["a","d"], "d":["e"], "e":["d"] } print(graph)
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py {'a': ['b', 'c'], 'b': ['a', 'd'], 'c': ['a', 'd'], 'd': ['e'], 'e': ['d']} Process finished with exit code 0
2. Display the vertices of the graph
To display the vertices of the graph, simply find the keywords of the graph dictionary and use the keys() method
class graph: def __init__(self,gdict=None): if gdict is None: gdict = [] self.gdict = gdict #get the keys of the dictionary def getVertices(self): return list(self.gdict.keys()) #create the dictionary with graph elements graph_elements ={ "a" : ["b","c"], "b" : ["a", "d"], "c" : ["a", "d"], "d" : ["e"], "e" : ["d"] } g=graph(graph_elements) print(g.getVertices())
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py ['a', 'b', 'c', 'd', 'e'] Process finished with exit code 0
Show the edges of the diagram (later understood)
Finding graph edges is less than vertices, because you must find vertices with one edge between each pair of vertices. Therefore, create an empty list of edges, and then iterate over the edge values associated with each vertex. A list forms edges that contain different groups of edges found from vertices.
[{'a', 'b'}, {'c', 'a'}, {'d', 'b'}, {'c', 'd'}, {'d', 'e'}]
Add a vertex
class graph: def __init__(self,gdict=None): if gdict is None: gdict = [] self.gdict = gdict #get the keys of the dictionary def getVertices(self): return list(self.gdict.keys()) #add the vertex as a key def addVertex(self,vrtx): if vrtx not in self.gdict: self.gdict[vrtx] = [] #create the dictionary with graph elements graph_elements ={ "a" : ["b","c"], "b" : ["a", "d"], "c" : ["a", "d"], "d" : ["e"], "e" : ["d"] } g=graph(graph_elements) print(g.getVertices()) g.addVertex("f") print(g.getVertices())
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py ['a', 'b', 'c', 'd', 'e'] ['a', 'b', 'c', 'd', 'e', 'f'] Process finished with exit code 0
Add edge
Adding an edge to an existing graph involves treating the new vertex as a tuple and verifying that the edge already exists. If it does not exist, add an edge
class graph: def __init__(self,gdict=None): if gdict is None: gdict = {} self.gdict = gdict def edges(self): return self.findedges() #add the new edge #The so-called adding edge is to abstract the number into the form of a dictionary def AddEdge(self,edge): edge = set(edge) (vrtx1,vrtx2) = tuple(edge) if vrtx1 in self.gdict: self.gdict[vrtx1].append(vrtx2) else: self.gdict[vrtx1] = [vrtx2] #list the edge names #The combination of printing edge, is an edge def findedges(self): edgename = [] for vrtx in self.gdict: for nxtvrtx in self.gdict[vrtx]: #key if not in edgename: edgename.append() return edgename # Create the dictionary with graph elements graph_elements = { "a" : ["b","c"], "b" : ["a", "d"], "c" : ["a", "d"], "d" : ["e"], "e" : ["d"] } g = graph(graph_elements) g.AddEdge({'a','e'}) g.AddEdge({'a','c'}) print(g.edges())
F:\7-9 Practice code\fuxi\venv\Scripts\python.exe F:/7-9 Practice code/fuxi/shujujiegou.py [{'a', 'b'}, {'c', 'a'}, {'a', 'e'}, {'d', 'b'}, {'c', 'd'}, {'e', 'd'}] Process finished with exit code 0