Home > Backend Development > Python Tutorial > In-depth understanding of Python collection module and deep and shallow copy

In-depth understanding of Python collection module and deep and shallow copy

高洛峰
Release: 2017-03-15 13:27:23
Original
2006 people have browsed it

ccollection module is an extension of Python's general built-in containers: dictionary, list, tuple and set. It contains some professional containersdata types :

Counter (counter): dict subclass, used to count the number of hashable objects.

OrderedDict (ordered dictionary): dict subclass, recording the order in which data members are added.

defaultdict (default dictionary): dict subclass, calling a factory function to provide a default value for missing values ​​of dict.

namedtuple (named tuple): The factory function generates a tuple subclass with named fields.

deque (two-way queue): A function that can quickly dequeue and join the queue at both ends of the "queue", similar to the queue (list-like) container.

ChainMap: A dictionary-like type that creates a single view for multiple maps.

UserDict: Wrapping a dictionary makes it easier to create subclasses of the dictionary.

UserList: Wrapping the list object makes it easier to create subclasses of the list.

UserString: Wrapping a String object makes it easier to create subclasses of String.

1. Counter (counter)

Counter is a subclass of dict, used to count hashable objects. It is an unordered container with elements stored as dictionary keys and count values ​​as dictionary values. Count allows any integer value, including zero or negative counts. The Counter class is similar to language classes such as bags or multisets.

Its elements are counted from an iterable object, or initialized from another map (or counter).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

class Counter(dict):

    '''Dict subclass for counting hashable items.  Sometimes called a bag

    or multiset.  Elements are stored as dictionary keys and their counts

    are stored as dictionary values.

 

    >>> c = Counter('abcdeabcdabcaba')  # count elements from a string

 

    >>> c.most_common(3)                # three most common elements

    [('a', 5), ('b', 4), ('c', 3)]

    >>> sorted(c)                       # list all unique elements

    ['a', 'b', 'c', 'd', 'e']

    >>> ''.join(sorted(c.elements()))   # list elements with repetitions

    'aaaaabbbbcccdde'

    >>> sum(c.values())                 # total of all counts

    15

 

    >>> c['a']                          # count of letter 'a'

    5

    >>> for elem in 'shazam':           # update counts from an iterable

    ...     c[elem] += 1                # by adding 1 to each element's count

    >>> c['a']                          # now there are seven 'a'

    7

    >>> del c['b']                      # remove all 'b'

    >>> c['b']                          # now there are zero 'b'

    0

 

    >>> d = Counter('simsalabim')       # make another counter

    >>> c.update(d)                     # add in the second counter

    >>> c['a']                          # now there are nine 'a'

    9

 

    >>> c.clear()                       # empty the counter

    >>> c

    Counter()

 

    Note:  If a count is set to zero or reduced to zero, it will remain

    in the counter until the entry is deleted or the counter is cleared:

 

    >>> c = Counter('aaabbc')

    >>> c['b'] -= 2                     # reduce the count of 'b' by two

    >>> c.most_common()                 # 'b' is still in, but its count is zero

    [('a', 3), ('c', 1), ('b', 0)]

 

    '''

    # References:

    #   http://en.wikipedia.org/wiki/Multiset

    #   http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html

    #   http://www.demo2s.com/Tutorial/Cpp/0380set-multiset/Catalog0380set-multiset.htm

    #   http://code.activestate.com/recipes/259174/

    #   Knuth, TAOCP Vol. II section 4.6.3

 

    def init(*args, **kwds):

        '''Create a new, empty Counter object.  And if given, count elements

        from an input iterable.  Or, initialize the count from another mapping

        of elements to their counts.

 

        >>> c = Counter()                           # a new, empty counter

        >>> c = Counter('gallahad')                 # a new counter from an iterable

        >>> c = Counter({'a': 4, 'b': 2})           # a new counter from a mapping

        >>> c = Counter(a=4, b=2)                   # a new counter from keyword args

 

        '''

        if not args:

            raise TypeError("descriptor 'init' of 'Counter' object "

                            "needs an argument")

        self, *args = args

        if len(args) > 1:

            raise TypeError('expected at most 1 arguments, got %d' % len(args))

        super(Counter, self).init()

        self.update(*args, **kwds)

 

    def missing(self, key):

        'The count of elements not in the Counter is zero.'

        # Needed so that self[missing_item] does not raise KeyError

        return 0

 

    def most_common(self, n=None):

        '''List the n most common elements and their counts from the most

        common to the least.  If n is None, then list all element counts.

 

        >>> Counter('abcdeabcdabcaba').most_common(3)

        [('a', 5), ('b', 4), ('c', 3)]

 

        '''

        # Emulate Bag.sortedByCount from Smalltalk

        if n is None:

            return sorted(self.items(), key=_itemgetter(1), reverse=True)

        return _heapq.nlargest(n, self.items(), key=_itemgetter(1))

 

    def elements(self):

        '''Iterator over elements repeating each as many times as its count.

 

        >>> c = Counter('ABCABC')

        >>> sorted(c.elements())

        ['A', 'A', 'B', 'B', 'C', 'C']

 

        # Knuth's example for prime factors of 1836:  2**2 * 3**3 * 17**1

        >>> prime_factors = Counter({2: 2, 3: 3, 17: 1})

        >>> product = 1

        >>> for factor in prime_factors.elements():     # loop over factors

        ...     product *= factor                       # and multiply them

        >>> product

        1836

 

        Note, if an element's count has been set to zero or is a negative

        number, elements() will ignore it.

 

        '''

        # Emulate Bag.do from Smalltalk and Multiset.begin from C++.

        return _chain.from_iterable(_starmap(_repeat, self.items()))

 

    # Override dict methods where necessary

 

    @classmethod

    def fromkeys(cls, iterable, v=None):

        # There is no equivalent method for counters because setting v=1

        # means that no element can have a count greater than one.

        raise NotImplementedError(

            'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')

 

    def update(*args, **kwds):

        '''Like dict.update() but add counts instead of replacing them.

 

        Source can be an iterable, a dictionary, or another Counter instance.

 

        >>> c = Counter('which')

        >>> c.update('witch')           # add elements from another iterable

        >>> d = Counter('watch')

        >>> c.update(d)                 # add elements from another counter

        >>> c['h']                      # four 'h' in which, witch, and watch

        4

 

        '''

        # The regular dict.update() operation makes no sense here because the

        # replace behavior results in the some of original untouched counts

        # being mixed-in with all of the other counts for a mismash that

        # doesn't have a straight-forward interpretation in most counting

        # contexts.  Instead, we implement straight-addition.  Both the inputs

        # and outputs are allowed to contain zero and negative counts.

 

        if not args:

            raise TypeError("descriptor 'update' of 'Counter' object "

                            "needs an argument")

        self, *args = args

        if len(args) > 1:

            raise TypeError('expected at most 1 arguments, got %d' % len(args))

        iterable = args[0] if args else None

        if iterable is not None:

            if isinstance(iterable, Mapping):

                if self:

                    self_get = self.get

                    for elem, count in iterable.items():

                        self[elem] = count + self_get(elem, 0)

                else:

                    super(Counter, self).update(iterable) # fast path when counter is empty

            else:

                _count_elements(self, iterable)

        if kwds:

            self.update(kwds)

 

    def subtract(*args, **kwds):

        '''Like dict.update() but subtracts counts instead of replacing them.

        Counts can be reduced below zero.  Both the inputs and outputs are

        allowed to contain zero and negative counts.

 

        Source can be an iterable, a dictionary, or another Counter instance.

 

        >>> c = Counter('which')

        >>> c.subtract('witch')             # subtract elements from another iterable

        >>> c.subtract(Counter('watch'))    # subtract elements from another counter

        >>> c['h']                          # 2 in which, minus 1 in witch, minus 1 in watch

        0

        >>> c['w']                          # 1 in which, minus 1 in witch, minus 1 in watch

        -1

 

        '''

        if not args:

            raise TypeError("descriptor 'subtract' of 'Counter' object "

                            "needs an argument")

        self, *args = args

        if len(args) > 1:

            raise TypeError('expected at most 1 arguments, got %d' % len(args))

        iterable = args[0] if args else None

        if iterable is not None:

            self_get = self.get

            if isinstance(iterable, Mapping):

                for elem, count in iterable.items():

                    self[elem] = self_get(elem, 0) - count

            else:

                for elem in iterable:

                    self[elem] = self_get(elem, 0) - 1

        if kwds:

            self.subtract(kwds)

 

    def copy(self):

        'Return a shallow copy.'

        return self.class(self)

 

    def reduce(self):

        return self.class, (dict(self),)

 

    def delitem(self, elem):

        'Like dict.delitem() but does not raise KeyError for missing values.'

        if elem in self:

            super().delitem(elem)

 

    def repr(self):

        if not self:

            return '%s()' % self.class.name

        try:

            items = ', '.join(map('%r: %r'.mod, self.most_common()))

            return '%s({%s})' % (self.class.name, items)

        except TypeError:

            # handle case where values are not orderable

            return '{0}({1!r})'.format(self.class.name, dict(self))

 

    # Multiset-style mathematical operations discussed in:

    #       Knuth TAOCP Volume II section 4.6.3 exercise 19

    #       and at http://en.wikipedia.org/wiki/Multiset

    #

    # Outputs guaranteed to only include positive counts.

    #

    # To strip negative and zero counts, add-in an empty counter:

    #       c += Counter()

 

    def add(self, other):

        '''Add counts from two counters.

 

        >>> Counter('abbb') + Counter('bcc')

        Counter({'b': 4, 'c': 2, 'a': 1})

 

        '''

        if not isinstance(other, Counter):

            return NotImplemented

        result = Counter()

        for elem, count in self.items():

            newcount = count + other[elem]

            if newcount > 0:

                result[elem] = newcount

        for elem, count in other.items():

            if elem not in self and count > 0:

                result[elem] = count

        return result

 

    def sub(self, other):

        ''' Subtract count, but keep only results with positive counts.

 

        >>> Counter('abbbc') - Counter('bccd')

        Counter({'b': 2, 'a': 1})

 

        '''

        if not isinstance(other, Counter):

            return NotImplemented

        result = Counter()

        for elem, count in self.items():

            newcount = count - other[elem]

            if newcount > 0:

                result[elem] = newcount

        for elem, count in other.items():

            if elem not in self and count < 0:

                result[elem] = 0 - count

        return result

 

    def or(self, other):

        &#39;&#39;&#39;Union is the maximum of value in either of the input counters.

 

        >>> Counter(&#39;abbb&#39;) | Counter(&#39;bcc&#39;)

        Counter({&#39;b&#39;: 3, &#39;c&#39;: 2, &#39;a&#39;: 1})

 

        &#39;&#39;&#39;

        if not isinstance(other, Counter):

            return NotImplemented

        result = Counter()

        for elem, count in self.items():

            other_count = other[elem]

            newcount = other_count if count < other_count else count

            if newcount > 0:

                result[elem] = newcount

        for elem, count in other.items():

            if elem not in self and count > 0:

                result[elem] = count

        return result

 

    def and(self, other):

        &#39;&#39;&#39; Intersection is the minimum of corresponding counts.

 

        >>> Counter(&#39;abbb&#39;) & Counter(&#39;bcc&#39;)

        Counter({&#39;b&#39;: 1})

 

        &#39;&#39;&#39;

        if not isinstance(other, Counter):

            return NotImplemented

        result = Counter()

        for elem, count in self.items():

            other_count = other[elem]

            newcount = count if count < other_count else other_count

            if newcount > 0:

                result[elem] = newcount

        return result

 

    def pos(self):

        &#39;Adds an empty counter, effectively stripping negative and zero counts&#39;

        result = Counter()

        for elem, count in self.items():

            if count > 0:

                result[elem] = count

        return result

 

    def neg(self):

        &#39;&#39;&#39;Subtracts from an empty counter.  Strips positive and zero counts,

        and flips the sign on negative counts.

 

        &#39;&#39;&#39;

        result = Counter()

        for elem, count in self.items():

            if count < 0:

                result[elem] = 0 - count

        return result

 

    def _keep_positive(self):

        &#39;&#39;&#39;Internal method to strip elements with a negative or zero count&#39;&#39;&#39;

        nonpositive = [elem for elem, count in self.items() if not count > 0]

        for elem in nonpositive:

            del self[elem]

        return self

 

    def iadd(self, other):

        &#39;&#39;&#39;Inplace add from another counter, keeping only positive counts.

 

        >>> c = Counter(&#39;abbb&#39;)

        >>> c += Counter(&#39;bcc&#39;)

        >>> c

        Counter({&#39;b&#39;: 4, &#39;c&#39;: 2, &#39;a&#39;: 1})

 

        &#39;&#39;&#39;

        for elem, count in other.items():

            self[elem] += count

        return self._keep_positive()

 

    def isub(self, other):

        &#39;&#39;&#39;Inplace subtract counter, but keep only results with positive counts.

 

        >>> c = Counter(&#39;abbbc&#39;)

        >>> c -= Counter(&#39;bccd&#39;)

        >>> c

        Counter({&#39;b&#39;: 2, &#39;a&#39;: 1})

 

        &#39;&#39;&#39;

        for elem, count in other.items():

            self[elem] -= count

        return self._keep_positive()

 

    def ior(self, other):

        &#39;&#39;&#39;Inplace union is the maximum of value from either counter.

 

        >>> c = Counter(&#39;abbb&#39;)

        >>> c |= Counter(&#39;bcc&#39;)

        >>> c

        Counter({&#39;b&#39;: 3, &#39;c&#39;: 2, &#39;a&#39;: 1})

 

        &#39;&#39;&#39;

        for elem, other_count in other.items():

            count = self[elem]

            if other_count > count:

                self[elem] = other_count

        return self._keep_positive()

 

    def iand(self, other):

        &#39;&#39;&#39;Inplace intersection is the minimum of corresponding counts.

 

        >>> c = Counter(&#39;abbb&#39;)

        >>> c &= Counter(&#39;bcc&#39;)

        >>> c

        Counter({&#39;b&#39;: 1})

 

        &#39;&#39;&#39;

        for elem, count in self.items():

            other_count = other[elem]

            if other_count < count:

                self[elem] = other_count

        return self._keep_positive()

 

Counter

Copy after login

1) Creation of counter:

1

2

3

4

5

6

from collections import Counter    #Counter 需要申明

 

a=Counter()                            # 创建空计数器

b=Counter(&#39;aabbbcccc&#39;)                 # 可迭代对象计数的方式创建对象

c = Counter({&#39;red&#39;: 4, &#39;blue&#39;: 2})     # 映射方法创建计数器

d = Counter(cats=4, dogs=8)            # 键值的方法创建计数器

Copy after login

2) Deletion of counter element

1

2

3

4

5

6

7

8

9

10

11

12

13

a=Counter({&#39;a&#39;:2,&#39;b&#39;:6,&#39;c&#39;:4,&#39;d&#39;:0,&#39;e&#39;:-2})

print(a)

a[&#39;a&#39;]=0    #修改了计数器元素里的值

print(a)

del a[&#39;b&#39;]   #删除了元素

print(a)

 

#运行结果

Counter({&#39;b&#39;: 6, &#39;c&#39;: 4, &#39;a&#39;: 2, &#39;d&#39;: 0, &#39;e&#39;: -2})

Counter({&#39;b&#39;: 6, &#39;c&#39;: 4, &#39;a&#39;: 0, &#39;d&#39;: 0, &#39;e&#39;: -2})

Counter({&#39;c&#39;: 4, &#39;a&#39;: 0, &#39;d&#39;: 0, &#39;e&#39;: -2})

 

del

Copy after login

3) Partial functions of counterAttributes

most_common(self, n=None):

Convert the counter into a list, the elements into a tuple, and return a list of the n most common elements and their counts, starting from the most Common to least common. If n is omitted or None, most_common() returns all elements in the counter. Elements with equal counts are ordered arbitrarily.

1

2

3

4

5

6

7

8

9

10

11

12

13

a=Counter({&#39;a&#39;:2,&#39;b&#39;:6,&#39;c&#39;:4,&#39;d&#39;:0,&#39;e&#39;:-2})

b=a.most_common()

c=a.most_common(2)

print(a)

print(b,type(b))

print(c,type(c))

 

#运行结果

Counter({&#39;b&#39;: 6, &#39;c&#39;: 4, &#39;a&#39;: 2, &#39;d&#39;: 0, &#39;e&#39;: -2})

[(&#39;b&#39;, 6), (&#39;c&#39;, 4), (&#39;a&#39;, 2), (&#39;d&#39;, 0), (&#39;e&#39;, -2)] <class &#39;list&#39;>

[(&#39;b&#39;, 6), (&#39;c&#39;, 4)] <class &#39;list&#39;>

 

demo

Copy after login

elements(self):

Returns an iterator that iterates over the elements a count of times. Elements are returned in random order. If the element's count is less than 1, elements() will ignore it.

1

2

3

4

5

6

7

8

9

10

11

12

13

a=Counter({&#39;a&#39;:2,&#39;b&#39;:6,&#39;c&#39;:4,&#39;d&#39;:0,&#39;e&#39;:-2})

b=a.elements()

c=sorted(a.elements())

print(a)

print(b,type(b))

print(c,type(c))

 

#运行结果

Counter({&#39;b&#39;: 6, &#39;c&#39;: 4, &#39;a&#39;: 2, &#39;d&#39;: 0, &#39;e&#39;: -2})

<itertools.chain object at 0x00225A50> <class &#39;itertools.chain&#39;>

[&#39;a&#39;, &#39;a&#39;, &#39;b&#39;, &#39;b&#39;, &#39;b&#39;, &#39;b&#39;, &#39;b&#39;, &#39;b&#39;, &#39;c&#39;, &#39;c&#39;, &#39;c&#39;, &#39;c&#39;] <class &#39;list&#39;>

 

demo

Copy after login

update(*args, **kwds):

Elements are counted from an iterable or incremented from another map (or counter). Like dict.update(), but increments counts instead of replacing them. Additionally, iterable objects should be a sequence of elements, not (key, value) pairs.

1

2

3

4

5

6

7

8

9

a=Counter({&#39;a&#39;:2,&#39;b&#39;:6,&#39;c&#39;:4,&#39;d&#39;:0,&#39;e&#39;:-2})

a.update(&#39;abe&#39;)

a.update({&#39;g&#39;:1})

print(a)

 

#运行结果

Counter({&#39;b&#39;: 7, &#39;c&#39;: 4, &#39;a&#39;: 3, &#39;g&#39;: 1, &#39;d&#39;: 0, &#39;e&#39;: -1})

 

demo

Copy after login

subtract(*args, **kwds):
Subtract elements from an iterable or another map (or counter). Like dict.update(), but subtracts counts instead of replacing them. Both input and output can be zero or negative.

1

2

3

4

5

6

7

8

a=Counter({&#39;a&#39;:2,&#39;b&#39;:6,&#39;c&#39;:4,&#39;d&#39;:0,&#39;e&#39;:-2})

a.subtract(&#39;ade&#39;)

print(a)

 

#运行结果

Counter({&#39;b&#39;: 6, &#39;c&#39;: 4, &#39;a&#39;: 1, &#39;d&#39;: -1, &#39;e&#39;: -3})

 

demo

Copy after login

2. Ordered Dictionary (OrderedDict)
Ordered dictionaries are similar to regular dictionaries, but they remember the order in which key-value pairs are inserted. When iterating over an ordered dictionary, items are returned in the order in which their keys were first added.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

class OrderedDict(dict):

    &#39;Dictionary that remembers insertion order&#39;

    # An inherited dict maps keys to values.

    # The inherited dict provides getitem, len, contains, and get.

    # The remaining methods are order-aware.

    # Big-O running times for all methods are the same as regular dictionaries.

 

    # The internal self.map dict maps keys to links in a doubly linked list.

    # The circular doubly linked list starts and ends with a sentinel element.

    # The sentinel element never gets deleted (this simplifies the algorithm).

    # The sentinel is in self.hardroot with a weakref proxy in self.root.

    # The prev links are weakref proxies (to prevent circular references).

    # Individual links are kept alive by the hard reference in self.map.

    # Those hard references disappear when a key is deleted from an OrderedDict.

 

    def init(*args, **kwds):

        &#39;&#39;&#39;Initialize an ordered dictionary.  The signature is the same as

        regular dictionaries, but keyword arguments are not recommended because

        their insertion order is arbitrary.

 

        &#39;&#39;&#39;

        if not args:

            raise TypeError("descriptor &#39;init&#39; of &#39;OrderedDict&#39; object "

                            "needs an argument")

        self, *args = args

        if len(args) > 1:

            raise TypeError(&#39;expected at most 1 arguments, got %d&#39; % len(args))

        try:

            self.root

        except AttributeError:

            self.hardroot = _Link()

            self.root = root = _proxy(self.hardroot)

            root.prev = root.next = root

            self.map = {}

        self.update(*args, **kwds)

 

    def setitem(self, key, value,

                    dict_setitem=dict.setitem, proxy=_proxy, Link=_Link):

        &#39;od.setitem(i, y) <==> od[i]=y&#39;

        # Setting a new item creates a new link at the end of the linked list,

        # and the inherited dictionary is updated with the new key/value pair.

        if key not in self:

            self.map[key] = link = Link()

            root = self.root

            last = root.prev

            link.prev, link.next, link.key = last, root, key

            last.next = link

            root.prev = proxy(link)

        dict_setitem(self, key, value)

 

    def delitem(self, key, dict_delitem=dict.delitem):

        &#39;od.delitem(y) <==> del od[y]&#39;

        # Deleting an existing item uses self.map to find the link which gets

        # removed by updating the links in the predecessor and successor nodes.

        dict_delitem(self, key)

        link = self.map.pop(key)

        link_prev = link.prev

        link_next = link.next

        link_prev.next = link_next

        link_next.prev = link_prev

        link.prev = None

        link.next = None

 

    def iter(self):

        &#39;od.iter() <==> iter(od)&#39;

        # Traverse the linked list in order.

        root = self.root

        curr = root.next

        while curr is not root:

            yield curr.key

            curr = curr.next

 

    def reversed(self):

        &#39;od.reversed() <==> reversed(od)&#39;

        # Traverse the linked list in reverse order.

        root = self.root

        curr = root.prev

        while curr is not root:

            yield curr.key

            curr = curr.prev

 

    def clear(self):

        &#39;od.clear() -> None.  Remove all items from od.&#39;

        root = self.root

        root.prev = root.next = root

        self.map.clear()

        dict.clear(self)

 

    def popitem(self, last=True):

        &#39;&#39;&#39;od.popitem() -> (k, v), return and remove a (key, value) pair.

        Pairs are returned in LIFO order if last is true or FIFO order if false.

 

        &#39;&#39;&#39;

        if not self:

            raise KeyError(&#39;dictionary is empty&#39;)

        root = self.root

        if last:

            link = root.prev

            link_prev = link.prev

            link_prev.next = root

            root.prev = link_prev

        else:

            link = root.next

            link_next = link.next

            root.next = link_next

            link_next.prev = root

        key = link.key

        del self.map[key]

        value = dict.pop(self, key)

        return key, value

 

    def move_to_end(self, key, last=True):

        &#39;&#39;&#39;Move an existing element to the end (or beginning if last==False).

 

        Raises KeyError if the element does not exist.

        When last=True, acts like a fast version of self[key]=self.pop(key).

 

        &#39;&#39;&#39;

        link = self.map[key]

        link_prev = link.prev

        link_next = link.next

        link_prev.next = link_next

        link_next.prev = link_prev

        root = self.root

        if last:

            last = root.prev

            link.prev = last

            link.next = root

            last.next = root.prev = link

        else:

            first = root.next

            link.prev = root

            link.next = first

            root.next = first.prev = link

 

    def sizeof(self):

        sizeof = _sys.getsizeof

        n = len(self) + 1                       # number of links including root

        size = sizeof(self.dict)            # instance dictionary

        size += sizeof(self.map) * 2          # internal dict and inherited dict

        size += sizeof(self.hardroot) * n     # link objects

        size += sizeof(self.root) * n         # proxy objects

        return size

 

    update = update = MutableMapping.update

 

    def keys(self):

        "D.keys() -> a set-like object providing a view on D&#39;s keys"

        return _OrderedDictKeysView(self)

 

    def items(self):

        "D.items() -> a set-like object providing a view on D&#39;s items"

        return _OrderedDictItemsView(self)

 

    def values(self):

        "D.values() -> an object providing a view on D&#39;s values"

        return _OrderedDictValuesView(self)

 

    ne = MutableMapping.ne

 

    marker = object()

 

    def pop(self, key, default=marker):

        &#39;&#39;&#39;od.pop(k[,d]) -> v, remove specified key and return the corresponding

        value.  If key is not found, d is returned if given, otherwise KeyError

        is raised.

 

        &#39;&#39;&#39;

        if key in self:

            result = self[key]

            del self[key]

            return result

        if default is self.marker:

            raise KeyError(key)

        return default

 

    def setdefault(self, key, default=None):

        &#39;od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od&#39;

        if key in self:

            return self[key]

        self[key] = default

        return default

 

    @_recursive_repr()

    def repr(self):

        &#39;od.repr() <==> repr(od)&#39;

        if not self:

            return &#39;%s()&#39; % (self.class.name,)

        return &#39;%s(%r)&#39; % (self.class.name, list(self.items()))

 

    def reduce(self):

        &#39;Return state information for pickling&#39;

        inst_dict = vars(self).copy()

        for k in vars(OrderedDict()):

            inst_dict.pop(k, None)

        return self.class, (), inst_dict or None, None, iter(self.items())

 

    def copy(self):

        &#39;od.copy() -> a shallow copy of od&#39;

        return self.class(self)

 

    @classmethod

    def fromkeys(cls, iterable, value=None):

        &#39;&#39;&#39;OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.

        If not specified, the value defaults to None.

 

        &#39;&#39;&#39;

        self = cls()

        for key in iterable:

            self[key] = value

        return self

 

    def eq(self, other):

        &#39;&#39;&#39;od.eq(y) <==> od==y.  Comparison to another OD is order-sensitive

        while comparison to a regular mapping is order-insensitive.

 

        &#39;&#39;&#39;

        if isinstance(other, OrderedDict):

            return dict.eq(self, other) and all(map(_eq, self, other))

        return dict.eq(self, other)

 

 

try:

    from _collections import OrderedDict

except ImportError:

    # Leave the pure Python version in place.

    pass

 

OrderedDict

Copy after login

1) Creation of ordered dictionary:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

from collections import OrderedDict

 

a=dict()                 #

b=OrderedDict()

a[&#39;a&#39;]=1

a[&#39;b&#39;]=2

a[&#39;c&#39;]=3

a[&#39;d&#39;]=4

b[&#39;a&#39;]=1

b[&#39;b&#39;]=2

b[&#39;c&#39;]=3

b[&#39;d&#39;]=4

print(a,type(a))

print(b,type(b))

 

#运行结果

{&#39;a&#39;: 1, &#39;c&#39;: 3, &#39;d&#39;: 4, &#39;b&#39;: 2} <class &#39;dict&#39;>  

OrderedDict([(&#39;a&#39;, 1), (&#39;b&#39;, 2), (&#39;c&#39;, 3), (&#39;d&#39;, 4)]) <class &#39;collections.OrderedDict&#39;>

 

demo

Copy after login

2) Function of ordered dictionary:
Ordered dictionary inherits the function of dictionary , only the functions different from the dictionary are introduced below. popitem(self, last=True):
Return and delete key-value pairs in the dictionary. If last is True (the default), these key-value pairs are returned in LIFO order, if False, they are returned in FIFO order.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

a=OrderedDict()

a[&#39;a&#39;]=1

a[&#39;b&#39;]=2

a[&#39;c&#39;]=3

a[&#39;d&#39;]=4

b=a.popitem()

print(a)

print(b)

 

#运行结果

OrderedDict([(&#39;a&#39;, 1), (&#39;b&#39;, 2), (&#39;c&#39;, 3)])

(&#39;d&#39;, 4)

 

demo

Copy after login

move_to_end(self, key, last=True):

Move an existing key to the other end of the ordered dictionary. If last is True (the default), the item is moved to the end, if last is False, it is moved to the beginning. If key does not exist, KeyError is raised.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

a=OrderedDict()

a[&#39;a&#39;]=1

a[&#39;b&#39;]=2

a[&#39;c&#39;]=3

a[&#39;d&#39;]=4

print(a)

b=a.move_to_end(&#39;b&#39;)

print(a)

 

#运行结果

OrderedDict([(&#39;a&#39;, 1), (&#39;b&#39;, 2), (&#39;c&#39;, 3), (&#39;d&#39;, 4)])

OrderedDict([(&#39;a&#39;, 1), (&#39;c&#39;, 3), (&#39;d&#39;, 4), (&#39;b&#39;, 2)])

 

demo

Copy after login

3. Default dictionary (defaultdict)

defaultdict can specify a default value for the dictionary, which can be a dictionary/list, etc. Returns a new dictionary-like object with the same functionality as the dict class.
Such as:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

from collections import defaultdict            

 

a=defaultdict(list)              #默认value为list

b=defaultdict(tuple)             #默认value为tuple

c=defaultdict(dict)             #默认value为dict

d=dict()

print(a)

print(b)

print(c)

print(d)

 

#运行结果

defaultdict(<class &#39;list&#39;>, {})

defaultdict(<class &#39;tuple&#39;>, {})

defaultdict(<class &#39;dict&#39;>, {})

{}

 

demo

Copy after login

Application:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

s = [(&#39;yellow&#39;, 1), (&#39;blue&#39;, 2), (&#39;yellow&#39;, 3), (&#39;blue&#39;, 4), (&#39;red&#39;, 1)]

d = defaultdict(list)

for k, v in s:

     d[k].append(v)            #如果使用普通字典,需要先给字典初始化键值对

c=sorted(d.items())

print(type(s))

print(d)

print(c,type(c))

 

#运行结果

<class &#39;list&#39;>

defaultdict(<class &#39;list&#39;>, {&#39;red&#39;: [1], &#39;blue&#39;: [2, 4], &#39;yellow&#39;: [1, 3]})

[(&#39;blue&#39;, [2, 4]), (&#39;red&#39;, [1]), (&#39;yellow&#39;, [1, 3])] <class &#39;list&#39;>

 

demo

Copy after login

Default dictionary function:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

class defaultdict(dict):

    """

    defaultdict(default_factory[, ...]) --> dict with default factory

     

    The default factory is called without arguments to produce

    a new value when a key is not present, in getitem only.

    A defaultdict compares equal to a dict with the same items.

    All remaining arguments are treated the same as if they were

    passed to the dict constructor, including keyword arguments.

    """

    def copy(self): # real signature unknown; restored from doc

        """ D.copy() -> a shallow copy of D. """

        pass

 

    def copy(self, *args, **kwargs): # real signature unknown

        """ D.copy() -> a shallow copy of D. """

        pass

 

    def getattribute(self, *args, **kwargs): # real signature unknown

        """ Return getattr(self, name). """

        pass

 

    def init(self, default_factory=None, **kwargs): # known case of _collections.defaultdict.init

        """

        defaultdict(default_factory[, ...]) --> dict with default factory

         

        The default factory is called without arguments to produce

        a new value when a key is not present, in getitem only.

        A defaultdict compares equal to a dict with the same items.

        All remaining arguments are treated the same as if they were

        passed to the dict constructor, including keyword arguments.

         

        # (copied from class doc)

        """

        pass

 

    def missing(self, key): # real signature unknown; restored from doc

        """

        missing(key) # Called by getitem for missing key; pseudo-code:

          if self.default_factory is None: raise KeyError((key,))

          self[key] = value = self.default_factory()

          return value

        """

        pass

 

    def reduce(self, *args, **kwargs): # real signature unknown

        """ Return state information for pickling. """

        pass

 

    def repr(self, *args, **kwargs): # real signature unknown

        """ Return repr(self). """

        pass

 

    default_factory = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    """Factory for default value called by missing()."""

 

defaultdict

Copy after login

4. Named tuple (namedtuple)

1) Description of named tuples

给元组中每个位置上的元素命名,它们可以使用常规的元组方法,可以让访问元素可以按名称而不是按位置索引

collections.namedtuple(typename, field_names, verbose=False, rename=False):

返回一个叫做 typename 的tuple子类,这个新的子类用来创建类tuple(tuple-like)的对象,这个对象拥有可以通过属性访问的字段,并且可以通过下标索引和迭代。

field_names 是一个单独的字符串,这个字符串中包含的所有字段用空格或逗号隔开,例如 'xy' 或 'x,y'.另外, field_names 也可以是字符串的列表,例如 ['x', 'y']。

如果verbose 为 True, 在类被建立后将打印类的定义。相反,它打印的是类的 _source 属性,也就是打印源代码。

如果 rename参数 为 True, 无效的field_names会被自动转换成位置的名称.例如, ['abc', 'def', 'ghi', 'abc'] 将被转换为 ['abc', '_1', 'ghi', '_3'], 来消除关键字 def 和重复的字段名 abc。

2)可命名元组的创建

需要先创建一个类。

1

2

3

4

5

6

7

8

9

10

11

from collections import namedtuple

 

myTupleClass=namedtuple(&#39;myTupleClass&#39;,[&#39;x&#39;,&#39;y&#39;])

a=point(1,2)

b=point(2,0)

print(a,a.x,a.y,type(a))

print(b,b.x,b.y,type(b))

 

#运行结果

myTupleClass(x=1, y=2) 1 2 <class &#39;main.myTupleClass&#39;>

myTupleClass(x=2, y=0) 2 0 <class &#39;main.myTupleClass&#39;>

Copy after login

3)可命名元组新创建类的功能属性

如上面创建的myTupleCalss类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

print(help(myTupleClass))    #运行help打印获取

 

class myTupleClass(builtins.tuple)

 |  myTupleClass(x, y)

 

 |  Method resolution order:

 |      myTupleClass

 |      builtins.tuple

 |      builtins.object

 

 |  Methods defined here:

 

 |  getnewargs(self)

 |      Return self as a plain tuple.  Used by copy and pickle.

 

 |  repr(self)

 |      Return a nicely formatted representation string

 

 |  _asdict(self)

 |      Return a new OrderedDict which maps field names to their values.

 

 |  _replace(_self, **kwds)

 |      Return a new myTupleClass object replacing specified fields with new values

 

 |  ----------------------------------------------------------------------

 |  Class methods defined here:

 

 |  _make(iterable, new=<built-in method new of type object at 0x6143B5C8>, len=<built-in function len>) from builtins.type

 |      Make a new myTupleClass object from a sequence or iterable

 

 |  ----------------------------------------------------------------------

 |  Static methods defined here:

 

 new(_cls, x, y)

 |      Create new instance of myTupleClass(x, y)

 

 |  ----------------------------------------------------------------------

 |  Data descriptors defined here:

 

 |  x

 |      Alias for field number 0

 

 |  y

 |      Alias for field number 1

 

 |  ----------------------------------------------------------------------

 |  Data and other attributes defined here:

 

 |  _fields = (&#39;x&#39;, &#39;y&#39;)

 

 |  _source = "from builtins import property as _property, tupl..._itemget...

 

 |  ----------------------------------------------------------------------

 |  Methods inherited from builtins.tuple:

 

 |  add(self, value, /)

 |      Return self+value.

 

 |  contains(self, key, /)

 |      Return key in self.

 

 |  eq(self, value, /)

 |      Return self==value.

 

 |  ge(self, value, /)

 |      Return self>=value.

 

 |  getattribute(self, name, /)

 |      Return getattr(self, name).

 

 |  getitem(self, key, /)

 |      Return self[key].

 

 |  gt(self, value, /)

 |      Return self>value.

 

 |  hash(self, /)

 |      Return hash(self).

 

 |  iter(self, /)

 |      Implement iter(self).

 

 |  le(self, value, /)

 |      Return self<=value.

 

 |  len(self, /)

 |      Return len(self).

 

 |  lt(self, value, /)

 |      Return self<value.

 

 |  mul(self, value, /)

 |      Return self*value.n

 

 |  ne(self, value, /)

 |      Return self!=value.

 

 |  rmul(self, value, /)

 |      Return self*value.

 

 count(...)

 |      T.count(value) -> integer -- return number of occurrences of value

 

 |  index(...)

 |      T.index(value, [start, [stop]]) -> integer -- return first index of value.

 |      Raises ValueError if the value is not present.

 

None

 

myTupleCalss

Copy after login

5.队列(deque)

1)双向队列(deque)

双向队列(Deque)是栈和队列的一般化。可以在两端添加和删除元素。

双向队列的创建:

1

2

3

4

5

6

7

8

9

10

from collections import deque

 

a=deque()

b=deque(&#39;abcd&#39;)

print(a,type(a))

print(b,type(b))

 

#运行结果

deque([]) <class &#39;collections.deque&#39;>

deque([&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;]) <class &#39;collections.deque&#39;>

Copy after login

双向队列的功能属性:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

class deque(object):

    """

    deque([iterable[, maxlen]]) --> deque object

     

    A list-like sequence optimized for data accesses near its endpoints.

    """

    def append(self, *args, **kwargs): # real signature unknown

        """ Add an element to the right side of the deque. """

        pass

 

    def appendleft(self, *args, **kwargs): # real signature unknown

        """ Add an element to the left side of the deque. """

        pass

 

    def clear(self, *args, **kwargs): # real signature unknown

        """ Remove all elements from the deque. """

        pass

 

    def copy(self, *args, **kwargs): # real signature unknown

        """ Return a shallow copy of a deque. """

        pass

 

    def count(self, value): # real signature unknown; restored from doc

        """ D.count(value) -> integer -- return number of occurrences of value """

        return 0

 

    def extend(self, *args, **kwargs): # real signature unknown

        """ Extend the right side of the deque with elements from the iterable """

        pass

 

    def extendleft(self, *args, **kwargs): # real signature unknown

        """ Extend the left side of the deque with elements from the iterable """

        pass

 

    def index(self, value, start=None, stop=None): # real signature unknown; restored from doc

        """

        D.index(value, [start, [stop]]) -> integer -- return first index of value.

        Raises ValueError if the value is not present.

        """

        return 0

 

    def insert(self, index, p_object): # real signature unknown; restored from doc

        """ D.insert(index, object) -- insert object before index """

        pass

 

    def pop(self, *args, **kwargs): # real signature unknown

        """ Remove and return the rightmost element. """

        pass

 

    def popleft(self, *args, **kwargs): # real signature unknown

        """ Remove and return the leftmost element. """

        pass

 

    def remove(self, value): # real signature unknown; restored from doc

        """ D.remove(value) -- remove first occurrence of value. """

        pass

 

    def reverse(self): # real signature unknown; restored from doc

        """ D.reverse() -- reverse *IN PLACE* """

        pass

 

    def rotate(self, *args, **kwargs): # real signature unknown

        """ Rotate the deque n steps to the right (default n=1).  If n is negative, rotates left. """

        pass

 

    def add(self, *args, **kwargs): # real signature unknown

        """ Return self+value. """

        pass

 

    def bool(self, *args, **kwargs): # real signature unknown

        """ self != 0 """

        pass

 

    def contains(self, *args, **kwargs): # real signature unknown

        """ Return key in self. """

        pass

 

    def copy(self, *args, **kwargs): # real signature unknown

        """ Return a shallow copy of a deque. """

        pass

 

    def delitem(self, *args, **kwargs): # real signature unknown

        """ Delete self[key]. """

        pass

 

    def eq(self, *args, **kwargs): # real signature unknown

        """ Return self==value. """

        pass

 

    def getattribute(self, *args, **kwargs): # real signature unknown

        """ Return getattr(self, name). """

        pass

 

    def getitem(self, *args, **kwargs): # real signature unknown

        """ Return self[key]. """

        pass

 

    def ge(self, *args, **kwargs): # real signature unknown

        """ Return self>=value. """

        pass

 

    def gt(self, *args, **kwargs): # real signature unknown

        """ Return self>value. """

        pass

 

    def iadd(self, *args, **kwargs): # real signature unknown

        """ Implement self+=value. """

        pass

 

    def imul(self, *args, **kwargs): # real signature unknown

        """ Implement self*=value. """

        pass

 

    def init(self, iterable=(), maxlen=None): # known case of _collections.deque.init

        """

        deque([iterable[, maxlen]]) --> deque object

         

        A list-like sequence optimized for data accesses near its endpoints.

        # (copied from class doc)

        """

        pass

 

    def iter(self, *args, **kwargs): # real signature unknown

        """ Implement iter(self). """

        pass

 

    def len(self, *args, **kwargs): # real signature unknown

        """ Return len(self). """

        pass

 

    def le(self, *args, **kwargs): # real signature unknown

        """ Return self<=value. """

        pass

 

    def lt(self, *args, **kwargs): # real signature unknown

        """ Return self<value. """

        pass

 

    def mul(self, *args, **kwargs): # real signature unknown

        """ Return self*value.n """

        pass

 

    @staticmethod # known case of new

    def new(*args, **kwargs): # real signature unknown

        """ Create and return a new object.  See help(type) for accurate signature. """

        pass

 

    def ne(self, *args, **kwargs): # real signature unknown

        """ Return self!=value. """

        pass

 

    def reduce(self, *args, **kwargs): # real signature unknown

        """ Return state information for pickling. """

        pass

 

    def repr(self, *args, **kwargs): # real signature unknown

        """ Return repr(self). """

        pass

 

    def reversed(self): # real signature unknown; restored from doc

        """ D.reversed() -- return a reverse iterator over the deque """

        pass

 

    def rmul(self, *args, **kwargs): # real signature unknown

        """ Return self*value. """

        pass

 

    def setitem(self, *args, **kwargs): # real signature unknown

        """ Set self[key] to value. """

        pass

 

    def sizeof(self): # real signature unknown; restored from doc

        """ D.sizeof() -- size of D in memory, in bytes """

        pass

 

    maxlen = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    """maximum size of a deque or None if unbounded"""

 

 

    hash = None

 

deque

Copy after login

2)单向队列(queue.Queue)

class queue.Queue(maxsize=0)

单向队列与双向队列的区别是FIFO(先进先出),maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被取出。如果maxsize小于或者等于0,则队列大小没有限制。

单向队列的创建:

1

2

3

4

5

6

7

8

9

10

import queue

 

a=queue.Queue()

b=queue.Queue(&#39;abcd&#39;)

print(a,type(a))

print(b,type(b))

 

#运行结果

<queue.Queue object at 0x00FBB310> <class &#39;queue.Queue&#39;>

<queue.Queue object at 0x01522DF0> <class &#39;queue.Queue&#39;>

Copy after login

单向队列的功能属性:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

class Queue:

    &#39;&#39;&#39;Create a queue object with a given maximum size.

 

    If maxsize is <= 0, the queue size is infinite.

    &#39;&#39;&#39;

 

    def init(self, maxsize=0):

        self.maxsize = maxsize

        self._init(maxsize)

 

        # mutex must be held whenever the queue is mutating.  All methods

        # that acquire mutex must release it before returning.  mutex

        # is shared between the three conditions, so acquiring and

        # releasing the conditions also acquires and releases mutex.

        self.mutex = threading.Lock()

 

        # Notify not_empty whenever an item is added to the queue; a

        # thread waiting to get is notified then.

        self.not_empty = threading.Condition(self.mutex)

 

        # Notify not_full whenever an item is removed from the queue;

        # a thread waiting to put is notified then.

        self.not_full = threading.Condition(self.mutex)

 

        # Notify all_tasks_done whenever the number of unfinished tasks

        # drops to zero; thread waiting to join() is notified to resume

        self.all_tasks_done = threading.Condition(self.mutex)

        self.unfinished_tasks = 0

 

    def task_done(self):

        &#39;&#39;&#39;Indicate that a formerly enqueued task is complete.

 

        Used by Queue consumer threads.  For each get() used to fetch a task,

        a subsequent call to task_done() tells the queue that the processing

        on the task is complete.

 

        If a join() is currently blocking, it will resume when all items

        have been processed (meaning that a task_done() call was received

        for every item that had been put() into the queue).

 

        Raises a ValueError if called more times than there were items

        placed in the queue.

        &#39;&#39;&#39;

        with self.all_tasks_done:

            unfinished = self.unfinished_tasks - 1

            if unfinished <= 0:

                if unfinished < 0:

                    raise ValueError(&#39;task_done() called too many times&#39;)

                self.all_tasks_done.notify_all()

            self.unfinished_tasks = unfinished

 

    def join(self):

        &#39;&#39;&#39;Blocks until all items in the Queue have been gotten and processed.

 

        The count of unfinished tasks goes up whenever an item is added to the

        queue. The count goes down whenever a consumer thread calls task_done()

        to indicate the item was retrieved and all work on it is complete.

 

        When the count of unfinished tasks drops to zero, join() unblocks.

        &#39;&#39;&#39;

        with self.all_tasks_done:

            while self.unfinished_tasks:

                self.all_tasks_done.wait()

 

    def qsize(self):

        &#39;&#39;&#39;Return the approximate size of the queue (not reliable!).&#39;&#39;&#39;

        with self.mutex:

            return self._qsize()

 

    def empty(self):

        &#39;&#39;&#39;Return True if the queue is empty, False otherwise (not reliable!).

 

        This method is likely to be removed at some point.  Use qsize() == 0

        as a direct substitute, but be aware that either approach risks a race

        condition where a queue can grow before the result of empty() or

        qsize() can be used.

 

        To create code that needs to wait for all queued tasks to be

        completed, the preferred technique is to use the join() method.

        &#39;&#39;&#39;

        with self.mutex:

            return not self._qsize()

 

    def full(self):

        &#39;&#39;&#39;Return True if the queue is full, False otherwise (not reliable!).

 

        This method is likely to be removed at some point.  Use qsize() >= n

        as a direct substitute, but be aware that either approach risks a race

        condition where a queue can shrink before the result of full() or

        qsize() can be used.

        &#39;&#39;&#39;

        with self.mutex:

            return 0 < self.maxsize <= self._qsize()

 

    def put(self, item, block=True, timeout=None):

        &#39;&#39;&#39;Put an item into the queue.

 

        If optional args &#39;block&#39; is true and &#39;timeout&#39; is None (the default),

        block if necessary until a free slot is available. If &#39;timeout&#39; is

        a non-negative number, it blocks at most &#39;timeout&#39; seconds and raises

        the Full exception if no free slot was available within that time.

        Otherwise (&#39;block&#39; is false), put an item on the queue if a free slot

        is immediately available, else raise the Full exception (&#39;timeout&#39;

        is ignored in that case).

        &#39;&#39;&#39;

        with self.not_full:

            if self.maxsize > 0:

                if not block:

                    if self._qsize() >= self.maxsize:

                        raise Full

                elif timeout is None:

                    while self._qsize() >= self.maxsize:

                        self.not_full.wait()

                elif timeout < 0:

                    raise ValueError("&#39;timeout&#39; must be a non-negative number")

                else:

                    endtime = time() + timeout

                    while self._qsize() >= self.maxsize:

                        remaining = endtime - time()

                        if remaining <= 0.0:

                            raise Full

                        self.not_full.wait(remaining)

            self._put(item)

            self.unfinished_tasks += 1

            self.not_empty.notify()

 

    def get(self, block=True, timeout=None):

        &#39;&#39;&#39;Remove and return an item from the queue.

 

        If optional args &#39;block&#39; is true and &#39;timeout&#39; is None (the default),

        block if necessary until an item is available. If &#39;timeout&#39; is

        a non-negative number, it blocks at most &#39;timeout&#39; seconds and raises

        the Empty exception if no item was available within that time.

        Otherwise (&#39;block&#39; is false), return an item if one is immediately

        available, else raise the Empty exception (&#39;timeout&#39; is ignored

        in that case).

        &#39;&#39;&#39;

        with self.not_empty:

            if not block:

                if not self._qsize():

                    raise Empty

            elif timeout is None:

                while not self._qsize():

                    self.not_empty.wait()

            elif timeout < 0:

                raise ValueError("&#39;timeout&#39; must be a non-negative number")

            else:

                endtime = time() + timeout

                while not self._qsize():

                    remaining = endtime - time()

                    if remaining <= 0.0:

                        raise Empty

                    self.not_empty.wait(remaining)

            item = self._get()

            self.not_full.notify()

            return item

 

    def put_nowait(self, item):

        &#39;&#39;&#39;Put an item into the queue without blocking.

 

        Only enqueue the item if a free slot is immediately available.

        Otherwise raise the Full exception.

        &#39;&#39;&#39;

        return self.put(item, block=False)

 

    def get_nowait(self):

        &#39;&#39;&#39;Remove and return an item from the queue without blocking.

 

        Only get an item if one is immediately available. Otherwise

        raise the Empty exception.

        &#39;&#39;&#39;

        return self.get(block=False)

 

    # Override these methods to implement other queue organizations

    # (e.g. stack or priority queue).

    # These will only be called with appropriate locks held

 

    # Initialize the queue representation

    def _init(self, maxsize):

        self.queue = deque()

 

    def _qsize(self):

        return len(self.queue)

 

    # Put a new item in the queue

    def _put(self, item):

        self.queue.append(item)

 

    # Get an item from the queue

    def _get(self):

        return self.queue.popleft()

 

queue.Queue

Copy after login

6.深浅拷贝

浅拷贝和深拷贝的主要区别在与操作后内存地址的变化是不同的。


The above is the detailed content of In-depth understanding of Python collection module and deep and shallow copy. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template