import threading
import traceback

class M(object):
	def __init__(self):
		self.lck = threading.Lock()
		self.d = {}

	def get(self, k, df=None):
		with self.lck:
			v = self.d.get(k, None)

		if v is None and df is not None:
			try:
				v, store = df()
				if store:
					with self.lck:
						self.d[k] = v
			except Exception:
				v = None
				print(traceback.format_exc())

		return v

	def put(self, k, v):
		with self.lck:
			old_v = self.d.get(k, None)
			self.d[k] = v
			return old_v

	def delete(self, k):
		with self.lck:
			old_v = self.d.get(k, None)

			try:
				del self.d[k]
			except Exception:
				pass

			return old_v

	def incr(self, k, i=1):
		with self.lck:
			old_v = self.d.get(k, 0)
			self.d[k] = old_v + i
			return old_v

	def decr(self, k, i=1):
		with self.lck:
			old_v = self.d.get(k, 0)
			self.d[k] = old_v - i
			return old_v

	def dict(self):
		with self.lck:
			return self.d.copy()

	def keys(self):
		with self.lck:
			return list(self.d.keys())

	def values(self):
		with self.lck:
			return list(self.d.values())

	def clear(self, m={}):
		with self.lck:
			self.d = m

	def filter(self, f):
		with self.lck:
			for k in list(self.d.keys()):
				v = f(k, self.d[k])
				if v:
					self.d[k] = v
				else:
					del self.d[k]

	def __len__(self):
		with self.lck:
			return len(self.d)

class O(object):
	def __init__(self, **kw):
		self.__dict__.update(kw)

class Counter(object):
	def __init__(self):
		self.n = 0
		self.lck = threading.Lock()

	def next(self):
		with self.lck:
			self.n += 1
			return self.n

def filter_bool(it):
	return [v for v in it if v]

def filter_none(it):
	return [v for v in it if v is not None]

def id(v):
	return v

def filter_join(it, sep='', out=None):
	if not out:
		out = id
	return sep.join((out(v) for v in it if v))

@@ -1123,16 +1123,25 @@
 (self, f
+, keys=%5B%5D
 ):%0A%09%09wit
@@ -1159,16 +1159,31 @@
 %0A%09%09%09
-for k in
+if not keys:%0A%09%09%09%09keys =
  lis
@@ -1198,16 +1198,34 @@
 .keys())
+%0A%0A%09%09%09for k in keys
 :%0A%09%09%09%09v 
@@ -1237,19 +1237,23 @@
 , self.d
-%5Bk%5D
+.get(k)
 )%0A%09%09%09%09if
@@ -1285,16 +1285,27 @@
 %09%09else:%0A
+%09%09%09%09%09try:%0A%09
 %09%09%09%09%09del
@@ -1314,16 +1314,49 @@
 elf.d%5Bk%5D
+%0A%09%09%09%09%09except KeyError:%0A%09%09%09%09%09%09pass
 %0A%0A%09def _

Allow a caller of kv.M.filter to specify the list of keys