def parse_runner_book(book):
back_levels = []
lay_levels = []
order_book = {'batb': [], 'batl': []}
for level in book:
for side, order in level.items():
if order:
side = price_side_map.get(side)
if side == 'back':
bisect.insort(back_levels, floatify(order.get('Price')))
order_book['batb'].append([floatify(order.get('Price')), floatify(order.get('Stake'))])
elif side == 'lay':
bisect.insort_right(lay_levels, floatify(order.get('Price')))
order_book['batl'].append([floatify(order.get('Price')), floatify(order.get('Stake'))])
back_levels.reverse()
order_book['batb'] = [[back_levels.index(x[0]), x[0], x[1]] for x in order_book['batb']]
order_book['batl'] = [[lay_levels.index(x[0]), x[0], x[1]] for x in order_book['batl']]
return order_book
python类insort_right()的实例源码
def insort_right_rev(alist, new_element, low=0, high=None):
"""Similar to bisect.insort_right but for reverse sorted lists
This code is similar to the Python code found in Lib/bisect.py.
We simply change the comparison from 'less than' to 'greater than'.
"""
if low < 0:
raise ValueError('low must be non-negative')
if high is None:
high = len(alist)
while low < high:
middle = (low + high) // 2
if new_element > alist[middle]:
high = middle
else:
low = middle + 1
alist.insert(low, new_element)
def insort_right_rev(alist, new_element, low=0, high=None):
"""Similar to bisect.insort_right but for reverse sorted lists
This code is similar to the Python code found in Lib/bisect.py.
We simply change the comparison from 'less than' to 'greater than'.
"""
if low < 0:
raise ValueError('low must be non-negative')
if high is None:
high = len(alist)
while low < high:
middle = (low + high) // 2
if new_element > alist[middle]:
high = middle
else:
low = middle + 1
alist.insert(low, new_element)
def attachChild(self, newChild, index = None):
"""
Attach a (parentless) child. If the child has a parent
already, call its reattach method
"""
# Don't allow bidirectional parenthood
assert not self is newChild
if newChild.parent():
raise AttachmentError('Cannot attach node: %s to: %s Node is already attached to %s' \
% (newChild.prettyPrint(), self.prettyPrint(), newChild.parent().prettyPrint()))
if index == None:
if not self._children:
self._children.append(newChild)
else:
bisect.insort_right(self._children, newChild)
else:
self._children.insert(index, newChild)
newChild.setParent(self)
def _cache(self, item: CacheItem):
scope = item.scope
if item.key in self.cache:
raise Exception("Added same item twice")
self.cache[item.key] = item
if scope.version != 0:
try:
self.keysforVersion[scope.version].add(item.key)
except KeyError:
raise Exception("Added data to version that is not open")
bisect.insort_right(self.timerqueue, item)
if item.time < self.nextAction:
self.nextAction = item.time
self._advance_time()
def insort_right_rev(alist, new_element, low=0, high=None):
"""Similar to bisect.insort_right but for reverse sorted lists
This code is similar to the Python code found in Lib/bisect.py.
We simply change the comparison from 'less than' to 'greater than'.
"""
if low < 0:
raise ValueError('low must be non-negative')
if high is None:
high = len(alist)
while low < high:
middle = (low + high) // 2
if new_element > alist[middle]:
high = middle
else:
low = middle + 1
alist.insert(low, new_element)
def add_partition(self, key, group):
"""Add sharding information for a group"""
if self.shard_type == 'RANGE':
key = int(key)
elif self.shard_type == 'RANGE_DATETIME':
try:
if ':' in key:
key = datetime.strptime(key, "%Y-%m-%d %H:%M:%S")
else:
key = datetime.strptime(key, "%Y-%m-%d").date()
except:
raise ValueError(
"RANGE_DATETIME key could not be parsed, was: {0}".format(
key
))
elif self.shard_type == 'RANGE_STRING':
pass
elif self.shard_type == "HASH":
pass
else:
raise ValueError("Unsupported sharding type {0}".format(
self.shard_type
))
self.partitioning[key] = {
'group': group,
}
self.reset_ttl()
bisect.insort_right(self.keys, key)
insort_right_rev(self.keys_reversed, key)
def add_partition(self, key, group):
"""Add sharding information for a group"""
if self.shard_type == 'RANGE':
key = int(key)
elif self.shard_type == 'RANGE_DATETIME':
try:
if ':' in key:
key = datetime.strptime(key, "%Y-%m-%d %H:%M:%S")
else:
key = datetime.strptime(key, "%Y-%m-%d").date()
except:
raise ValueError(
"RANGE_DATETIME key could not be parsed, was: {0}".format(
key
))
elif self.shard_type == 'RANGE_STRING':
pass
elif self.shard_type == "HASH":
pass
else:
raise ValueError("Unsupported sharding type {0}".format(
self.shard_type
))
self.partitioning[key] = {
'group': group,
}
self.reset_ttl()
bisect.insort_right(self.keys, key)
insort_right_rev(self.keys_reversed, key)
def add_partition(self, key, group):
"""Add sharding information for a group"""
if self.shard_type == 'RANGE':
key = int(key)
elif self.shard_type == 'RANGE_DATETIME':
try:
if ':' in key:
key = datetime.strptime(key, "%Y-%m-%d %H:%M:%S")
else:
key = datetime.strptime(key, "%Y-%m-%d").date()
except:
raise ValueError(
"RANGE_DATETIME key could not be parsed, was: {0}".format(
key
))
elif self.shard_type == 'RANGE_STRING':
pass
elif self.shard_type == "HASH":
pass
else:
raise ValueError("Unsupported sharding type {0}".format(
self.shard_type
))
self.partitioning[key] = {
'group': group,
}
self.reset_ttl()
bisect.insort_right(self.keys, key)
insort_right_rev(self.keys_reversed, key)
def run(self):
class Retweet(object):
def __init__(self, id, count):
self.id = id
self.count = count
def __lt__(self, other):
# a trick to have bisect reverse sort
return self.count > other.count
def __repr__(self):
return "%s [%s]" % (self.id, self.count)
retweet_ids = set()
retweets = []
for tweet_str in self.input().open('r'):
tweet = json.loads(tweet_str)
retweet_count = tweet.get('retweet_count', 0)
if retweet_count == 0:
continue
if 'retweeted_status' in tweet:
tweet_id = tweet['retweeted_status']['id_str']
else:
tweet_id = tweet['id_str']
# ignore duplicate tweets
# NOTE: this only works for search data!
if tweet_id in retweet_ids:
continue
bisect.insort_right(
retweets,
Retweet(tweet_id, retweet_count)
)
retweet_ids.add(tweet_id)
if len(retweets) > 100:
rt = retweets.pop()
retweet_ids.remove(rt.id)
with self.output().open('w') as fh:
writer = csv.DictWriter(fh, delimiter=',',
quoting=csv.QUOTE_MINIMAL,
fieldnames=['tweet_id', 'count'])
writer.writeheader()
for rt in retweets:
writer.writerow({'tweet_id': rt.id, 'count': rt.count})