Skip to content

Latest commit

 

History

History
174 lines (131 loc) · 4.42 KB

walkthrough.md

File metadata and controls

174 lines (131 loc) · 4.42 KB

Walkthrough

This acts as a guided overview of how to utilize WeightedList in Python.

Instantiation

Creating a WeightedList is similar to creating a list, except each item should be a weight-value pair, such as a tuple:

wl = WeightedList(
  (2, "sup"),
  (7, "nova"),
  (13, "shard"),
  ...
)

Note that the weight always comes first, so that it consistently aligns. [^0]

Keyword arguments can also be used, where each key and value correspond to an item value and weight, respectively:

wl = WeightedList(sup = 2, nova = 7)

However, note that this only allows str values with no spaces or duplicates.

Many methods involve ‘compatible iterables’. This refers to any sequence or mapping that can be unpacked during instantiation to provide arguments, shown above.

For sequences, they must consist of item pairs where the weight comes first. For mappings, keys and values correspond to item values and weights, respectively.

Indexing

The items in a WeightedList are stored as WeightedItem objects, which have a value and weight attribute. When indexing the list, these objects are returned:

>>> wl[0]
WeightedItem('sup', 2)
>>> wl[0].value
'sup'
>>> wl[0].weight
2

A WeightedList uses weighted indexing, which drives the weighting machanic. The weight of each item can be thought of as how many times that object is repeated.

>>> wl[0].value
'sup'
>>> wl[1].value
'sup'
>>> wl[2].value
'nova'
>>> wl[8].value
'nova'

Calling len() on it, notice that the length takes weights into account:

>>> len(wl)
9
# 'sup' has a weight of 2
# 'nova' has a weight of 7
# the length (total weight) is 9

Selection

The most important method, that the whole class essentially revolves around, is self.select(). This randomly selects an item from the list, taking weights into account. Items with higher weight have a higher chance of being selected, and vice versa for lower weights.

The simplest way is calling it with no arguments:

>>> wl.select()
'nova'

This selects a single item, and returns its value. To obtain the item itself (which would allow its weight to be accessed), set depth to True:

>>> wl.select(depth = True)
WeightedItem('sup', 2)

Multiple items can be selected at once, by passing in an int:

>>> wl.select(2)
['nova', 'nova']

2 ints can be passed, to select a random number of items between those 2 numbers (inclusive):

# selects anywhere between 1 to 10 items
>>> wl.select(1, 10)
[...]

This selects items with replacement, which means the ‘same’ item can be selected more than once. To select without replacement, set replace to False:

>>> wl.select(20, replace = False)
['nova', 'nova', 'sup', 'nova', 'nova', 'nova', 'nova', 'sup', 'nova']

Modification

All the regular methods a list can be used on a WeightedList; however, some work slightly differently.

All return the modified list afterwards, to allow for chaining should you wish to do so:

>>> wl = (WeightedList(...)
.clear()
.append(2, "sup")
.append(7, "nova")
.shuffle()
.cluster(3)
.deviate()
.increment(-2)
.extrapolate()
)

append() takes 2 arguments, a value and weight. Again, the weight comes first, for alignment:

>>> wl.append(13, "shard")
WeightedList(('sup', 2), ('nova', 7), ('shard', 13))

If no weight is passed, it defaults to 1:

>>> wl.append("sip")
WeightedList(('sup', 2), ('nova', 7), ('shard', 13), ('sip', 1))

extend() can take multiple iterables as arguments. These can be WeightedLists or any compatible iterables.

Manipulation

Weights can be manipulated through various methods to distort or change weightings.

increment changes all weights by a particular amount, which can be negative.

>>> wl.increment()
WeightedList(('sup', 3), ('nova', 8))
>>> wl.increment(2)
WeightedList(('sup', 5), ('nova', 10))
>>> wl.increment(-4)
WeightedList(('sup', 1), ('nova', 6))

Increasing all weights has the effect of lessening the relative difference between them, and vice versa for decreasing.

Conversion

It may be useful to convert a WeightedList to another data type for transfer or storage.

The values and weights can be accessed through those respective properties:

>>> wl.values
['sup', 'nova']
>>> wl.weights
[2, 7]

list and dict representations can be extracted too:

>>> wl.list
[[2, 'sup'], [7, 'nova']]
>>> wl.dict
{'sup': 2, 'nova': 7}