我从Scala上读到的内容并没有立即清楚地使用符号文字.有人愿意分享一些现实世界的用途吗?
符号文字是否包含特定的Java习语?哪些语言有相似的结构?我来自Python背景,不确定那种语言有什么类似的东西.
什么会激励我使用'HelloWorld vs"HelloWorld"?
谢谢
是否有Python等效的Ruby符号?
如果是的话那么它是什么?
如果没有,那么我们是不是只使用字符串作为字典中的键?
据我所知,Python中的变量只是指针.
基于此规则,我可以假设此代码段的结果:
i = 5
j = i
j = 3
print(i)
Run Code Online (Sandbox Code Playgroud)
会的3.但是我得到了一个意想不到的结果,是的5.
此外,我的Python书确实涵盖了这个例子:
i = [1,2,3]
j = i
i[0] = 5
print(j)
Run Code Online (Sandbox Code Playgroud)
结果将是[5,2,3].
我理解错了什么?
谁可以给我解释一下这个?所以我一直在python中使用id()命令,并遇到了这个:
>>> id('cat')
5181152
>>> a = 'cat'
>>> b = 'cat'
>>> id(a)
5181152
>>> id(b)
5181152
Run Code Online (Sandbox Code Playgroud)
除了一部分之外,这对我有意义:字符串'cat'在我将其分配给变量之前在内存中有一个地址.我可能只是不明白内存寻址是如何工作的,但是有人可以向我解释这一点,或者至少告诉我应该读一下内存寻址吗?
所以这一切都很好,但这让我更加困惑:
>>> a = a[0:2]+'t'
>>> a
'cat'
>>> id(a)
39964224
>>> id('cat')
5181152
Run Code Online (Sandbox Code Playgroud)
这让我感到很奇怪,因为'cat'是一个地址为5181152的字符串,但是新的a具有不同的地址.所以,如果内存中有两个'cat'字符串,为什么不为id('cat')打印两个地址?我最后的想法是连接与地址的变化有关,所以我尝试了这个:
>>> id(b[0:2]+'t')
39921024
>>> b = b[0:2]+'t'
>>> b
'cat'
>>> id(b)
40000896
Run Code Online (Sandbox Code Playgroud)
我本来可以预测ID是相同的,但事实并非如此.思考?
在我目前的一个侧面项目中,我正在扫描一些文本,查看三元组词的频率.在我第一次使用它时,我使用了三级深度的默认字典.换句话说,topDict[word1][word2][word3]返回这些单词在文本中出现的次数,topDict[word1][word2]返回包含单词1和2后面出现的所有单词的字典等.
这功能正常,但内存非常密集.在我的初始测试中,它使用了将三元组存储在文本文件中的内存的20倍,这看起来像是一个过大的内存开销.
我怀疑这些词典中的许多都是使用比实际使用的更多的插槽创建的,所以我想用这种方式使用更高效的内存来替换字典.我强烈希望有一种解决方案,允许按字典的方式进行键查找.
根据我所知的数据结构,使用红黑或AVL之类的平衡二叉搜索树可能是理想的,但我真的不想自己实现它们.如果可能的话,我宁愿坚持使用标准的python库,但如果它们最好的话,我肯定会接受其他选择.
那么,有没有人对我有任何建议?
编辑添加:
感谢到目前为止的回复.到目前为止,一些答案建议使用元组,当我将前两个单词浓缩为元组时,这对我来说并没有什么作用.我很犹豫要把所有这三个用作关键因为我希望它能够很容易地查找前两个字的所有第三个字.(即我想要的结果topDict[word1, word2].keys()).
我正在玩的当前数据集是维基百科学校的最新版本.例如,对于文本文件,解析前几千页的结果类似于11MB,其中每行是三个单词并且计数所有选项卡分开.以我现在使用的字典格式存储文本大约需要185MB.我知道指针和诸如此类的东西会有一些额外的开销,但差异似乎过大.
我正在编写一组python函数,对源代码项目执行某种一致性检查.我想为这些函数指定相当详细的名称,例如:check_5_theVersionOfAllVPropsMatchesTheVersionOfTheAutolinkHeader()
这样过长的名字会成为python的问题吗?属性名称是否有最大长度?
可能重复:
python 实习生做什么,什么时候应该使用?
我正在使用python中的程序,该程序必须在数组上关联数百万个字符串对象.我发现如果它们都来自相同的带引号的字符串,则每个附加的"字符串"只是对第一个主字符串的引用.但是,如果从文件中读取字符串,并且字符串全部相等,则每个字符串仍然需要新的内存分配.
也就是说,这需要大约14meg的存储空间:
a = ["foo" for a in range(0,1000000)]
Run Code Online (Sandbox Code Playgroud)
虽然这需要超过65meg的存储空间:
a = ["foo".replace("o","1") for a in range(0,1000000)]
Run Code Online (Sandbox Code Playgroud)
现在我可以通过以下方式使内存占用更少的空间:
s = {"f11":"f11"}
a = [s["foo".replace("o","1")] for a in range(0,1000000)]
Run Code Online (Sandbox Code Playgroud)
但这似乎很愚蠢.有更简单的方法吗?
我想我已经开始理解python了,但是我仍然遇到一个基本问题.什么时候用copy.copy?
>>>a=5
>>>b=a
>>>a=6
>>>print b
5
Run Code Online (Sandbox Code Playgroud)
好有意义.但在什么情况下说b=aa和b之间形成某种"链接",以便修改a会修改b?这是我没有得到的copy.copy- 每次使用等号将一个变量分配给另一个变量时,只需复制该值吗?
我有一个 Python 3.6 数据处理任务,它涉及预加载一个大字典,用于按 ID 查找日期,以便在多处理模块管理的子进程池的后续步骤中使用。这个过程占用了盒子上的大部分内存,所以我应用的一项优化是“实习”存储在字典中的字符串日期。正如我预期的那样,这将 dict 的内存占用减少了几个 GB,但它也产生了另一个意想不到的效果。
在应用实习之前,子进程在执行时会逐渐消耗越来越多的内存,我认为这是由于他们不得不将 dict 从全局内存逐渐复制到子进程的单独分配内存(这是运行Linux 等受益于 fork() 的写时复制行为。即使我没有更新子进程中的字典,看起来只读访问仍然可以通过引用计数触发写时复制。
我只希望实习能减少 dict 的内存占用,但实际上它也阻止了内存使用量在子进程生命周期中逐渐增加。
这是我能够构建的一个复制行为的最小示例,尽管它需要一个大文件来加载并填充 dict 以及在值中进行足够数量的重复以确保实习提供好处。
import multiprocessing
import sys
# initialise a large dict that will be visible to all processes
# that contains a lot of repeated values
global_map = dict()
with open(sys.argv[1], 'r', encoding='utf-8') as file:
if len(sys.argv) > 2:
print('interning is on')
else:
print('interning is off')
for i, line in enumerate(file):
if i > 30000000:
break
parts …Run Code Online (Sandbox Code Playgroud) 以下两个代码是等效的,但是第一个大约占用700M内存,后一个仅占用约100M内存(通过Windows任务管理器)。这里会发生什么?
def a():
lst = []
for i in range(10**7):
t = "a"
t = t * 2
lst.append(t)
return lst
_ = a()
Run Code Online (Sandbox Code Playgroud)
def a():
lst = []
for i in range(10**7):
t = "a" * 2
lst.append(t)
return lst
_ = a()
Run Code Online (Sandbox Code Playgroud) 我知道在python中,每个标识符或变量名都是对实际对象的引用.
a = "hello"
b = "hello"
Run Code Online (Sandbox Code Playgroud)
当我比较两个字符串
a == b
Run Code Online (Sandbox Code Playgroud)
输出是
True
Run Code Online (Sandbox Code Playgroud)
如果我用Java编写等效代码,输出将是false因为比较是在引用(不同)之间,而不是实际对象.
所以我在这里看到的是,在运行时解释器将引用(变量名称)替换为实际对象.
因此,我可以安全地假设"每次解释器看到已经分配的变量名称时,它都会将其替换为它所指的对象"?我用谷歌搜索,但找不到我想要的任何合适的答案.
for count in range(5):
str1 = 'a' * count
str2 = 'a' * count
print(id(str1) == id(str2))
Output:
True
True
False
False
False
Run Code Online (Sandbox Code Playgroud)
为什么我们会虚假,因为
str1 = 'aaa'
str2 = 'aaa'
print(id(str1) == id(str2)) # True
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释这种python内存行为。
我看一下python代码,其中字符串变量赋值如下所示:
var1 = var2[:]
Run Code Online (Sandbox Code Playgroud)
我只是想知道有什么区别:
var1 = var2
Run Code Online (Sandbox Code Playgroud)
这是我的实验:
>>> original = "some text"
>>> copy1 = original
>>> copy2 = original[:]
>>> original = "another text"
>>> copy1
'some text'
>>> copy2
'some text'
Run Code Online (Sandbox Code Playgroud)
更新:
这是一个完整的代码.此代码搜索替换密码的密钥.如果我删除'[:]',这段代码将非常缓慢.
python ×12
cpython ×2
python-2.7 ×2
python-3.x ×2
dictionary ×1
identifier ×1
linux ×1
memory ×1
pointers ×1
ruby ×1
scala ×1
symbols ×1
syntax ×1
variables ×1