是否可以将其转换为字典理解?我怎么知道呢 什么可以转换,什么不可以?
console
答案 0 :(得分:2)
事实上,你可以使用词典理解,但你不应该。如果你准备好了,我们走了。
我将首先对您的代码进行一些清理。
首先,我将cpPtr.split(" ")[0]
和cpPtr.split(" ")[1]
替换为u
和v
,其中u,v = cpPtr.split(" ")
。这是一个解构分配。
然后我内联以下几行:
if domainKey in domainAggregator.keys():
domainAggregator[domainKey] = int(domainAggregator[domainKey]) + int(u)
else:
domainAggregator[domainKey] = int(u)
成:
domainAggregator[domainKey] = int(domainAggregator[domainKey])+int(u) if domainKey in domainAggregator.keys() else int(u)
我现在得到以下代码:
for cpPtr in cpdomains:
u,v = cpPtr.split(" ")
for domainKey in self.domainSplitter(v):
domainAggregator[domainKey] = int(domainAggregator[domainKey])+int(u) if domainKey in domainAggregator.keys() else int(u)
我希望将其转化为字典理解。
现在,有些小黑客。
您不能在列表或词典理解中使用分配。为了把它放在列表理解中(然后是dict理解,见后面),我需要摆脱=
s:
u, v = cpPtr.split(" ")
...
domainAggregator[domainKey] = int(domainAggregator[domainKey])+int(u) if domainKey in domainAggregator.keys() else int(u)
变为:
for u, v in [cpPtr.split(" ")]: # this is a singleton
...
domainAggregator.update({domainKey:int(domainAggregator[domainKey])+int(u) if domainKey in domainAggregator.keys() else int(u)}) # I update the dict
代码现在是:
for cpPtr in cpdomains:
for u,v in [cpPtr.split(" ")]:
for domainKey in self.domainSplitter(v):
domainAggregator.update({domainKey:int(domainAggregator[domainKey])+int(u) if domainKey in domainAggregator.keys() else int(u)})
现在,我可以使用列表推导来创建副作用。你只需要在方括号内插入所有内容:
[domainAggregator.update({domainKey:int(domainAggregator[domainKey])+int(u) if domainKey in domainAggregator.keys() else int(u)}) for cpPtr in cpdomains for u,v in [cpPtr.split(" ")] for domainKey in self.domainSplitter(v)]
好的,在评估此表达式后,domainAggregator
具有预期值,但该列表只是None
的列表,因为dict.update
返回None
。
以下代码完全是疯了。不要试图在家里这样做!!!
是否可以创建一个返回正确值的字典理解?是!你必须在dict理解中创建副作用。我们试试这个:
# does not work
{k:v for k, v in domainAggregator if len( [domainAggregator.update({domainKey:(int(domainAggregator[domainKey]) if domainKey in domainAggregator.keys() else 0) + int(u)}) for cpPtr in cpdomains for u,v in [cpPtr.split(" ")] for domainKey in self.domainSplitter(v)])>=0}
表达式:
len([domainAggregator.update({domainKey:(int(domainAggregator[domainKey]) if domainKey in domainAggregator.keys() else 0) + int(u)}) for cpPtr in cpdomains for u,v in [cpPtr.split(" ")] for domainKey in self.domainSplitter(v))>=0
总是True
,您有所需的副作用。但是每次迭代这些项目时都会执行这种副作用,并且你会得到臭名昭着的RuntimeError: dictionary changed size during iteration
。
为避免这种情况,您只需触发一次副作用。
{k:v for da in [domainAggregator for _ in range(1) if len ([domainAggregator.update({domainKey:(int(domainAggregator[domainKey]) if domainKey in domainAggregator.keys() else 0) + int(u)}) for cpPtr in cpdomains for u,v in [cpPtr.split(" ")] for domainKey in self.domainSplitter(v)])>=0] for k,v in da.items()}
内部列表触发副作用并返回字典,外部字典理解遍历项目并创建字典。
不要这样做!!!
MVCE:Try it online!
答案 1 :(得分:1)
由于我在评论中解释的原因,我们无法真正将其转化为词典理解,但我们当然可以简化您所拥有的内容。使用$from = DB::table('sell_data')->select('vd_id')->selectRaw('count(vd_id) subCount')
->groupBy('vd_id');
$results = DB::query()
->select('vd_id', 'subCount')
->fromSub($from, 'sub')
->where('subCount', function($query) {
$query->selectRaw('count(vd_id) maxCount')
->from('sell_data')
->groupBy('vd_id')
->orderByDesc('maxCount')
->limit(1);
})
->orWhere('subCount', function($query) {
$query->selectRaw('count(vd_id) minCount')
->from('sell_data')
->groupBy('vd_id')
->orderBy('minCount')
->limit(1);
})
->get();
访问get()
元素,如果密钥不存在,我们可以提供默认值domainAggregator
,从而消除0
语句。
if