就地将排列应用于列表的方法? 按键排序的倒数

如何解决就地将排列应用于列表的方法? 按键排序的倒数

| 这是我想做的一个例子
spam_list = [\"We\",\"are\",\"the\",\"knights\",\"who\",\"say\",\"Ni\"]
spam_order = [0,1,2,4,5,6,3]
spam_list.magical_sort(spam_order)
print(spam_list)

[\"We\",\"Ni\",\"knights\"]
我可以用
enumerate
list
等来做,但我想直接影响
spam_list
,例如
list.sort()
,而不复制像
sorted()
编辑:推送一个字符串示例,以避免索引和and3ѭ的值之间的混淆 编辑:原来这是重复的Python排序并行数组吗?好吧,我不能为SO一致性参数付出太多努力。     

解决方法

您可以尝试:
spam_list = [spam_list[i] for i in spam_order]
    ,您可以给sort函数一个特殊的
key
order = dict(zip(spam_list,spam_order))
spam_list.sort(key=order.get)
编辑:正如@ninjagecko在他的答案中指出的那样,这并不是真正有效的方法,因为它会复制两个列表以创建用于查找的字典。但是,使用OP给出的修改示例,这是唯一的方法,因为必须建立一些索引。好处是,至少对于字符串而言,不会复制这些值,因此开销只是字典本身的开销。     ,  但我想直接影响spam_list,例如list.sort(),而不是像sorted()那样复制它 只有一个解决方案可以满足您的要求。每个其他解决方案都隐式地复制一个或两个列表(或将其转换为字典等)。您需要的是一种方法,该方法在原位对两个列表进行排序,使用的额外空间为[10],其中一个列表为另一个列表的键。我个人只是接受额外的空间复杂性,但是如果您确实想要,可以这样做: (编辑:原始海报可能并不真正在乎ѭ11,因为它很有效,而是因为它修改了状态;总的来说,这是一种危险的事情,并且是非低级语言尝试避免甚至禁止它,但是使用切片分配的解决方案将实现“就地”语义) 创建一个自定义词典子类(实际上是
Zip
类),该子类由要排序的两个列表支持。 索引
myZip[i]
->得到元组
(list1[i],list2[i])
分配
myZip[i]=(x1,x2)
->分派到
list1[i]=x1,list2[i]=x2
。 用它来做
myZip(spam_list,spam_order).sort()
,现在
spam_list
spam_order
都就地排序 例:
#!/usr/bin/python3

class LiveZip(list):
    def __init__(self,list1,list2):
        self.list1 = list1
        self.list2 = list2

    def __len__(self):
        return len(self.list1)

    def __getitem__(self,i):
        return (self.list1[i],self.list2[i])

    def __setitem__(self,i,tuple):
        x1,x2 = tuple
        self.list1[i] = x1
        self.list2[i] = x2

spam_list = [\"We\",\"are\",\"the\",\"knights\",\"who\",\"say\",\"Ni\"]
spam_order = [0,1,2,4,5,6,3]

#spam_list.magical_sort(spam_order)
proxy = LiveZip(spam_order,spam_list)
现在让我们看看它是否有效...
#proxy.sort()
#fail --> oops,the internal implementation is not meant to be subclassed! lame
# It turns out that the python [].sort method does NOT work without passing in
# a list to the constructor (i.e. the internal implementation does not use the
# public interface),so you HAVE to implement your own sort if you want to not
# use any extra space. This kind of dumb. But the approach above means you can 
# just use any standard textbook in-place sorting algorithm:
def myInPlaceSort(x):
    # [replace with in-place textbook sorting algorithm]
现在它可以工作了:
myInPlaceSort(proxy)

print(spam_list)
不幸的是,没有办法只对10个空格中的一个列表进行排序而不对另一个列表进行排序。如果您不想同时对两个列表进行排序,则不妨采用构建虚拟列表的原始方法。 但是,您可以执行以下操作:
spam_list.sort(key=lambda x:x)
但是,如果key或cmp函数对任何集合进行了任何引用(例如,如果传递了
dict.__getitem__
的字典,则必须构造),这并不比原始的
O(N)
空间方法好,除非您已经碰巧拥有这样的字典躺在周围。 原来这是重复出现的Python排序并行数组问题? ,但是除了这个问题之外,该问题也没有正确的答案,该答案与我的等效,但没有示例代码。除非您进行了令人难以置信的优化或专用代码,否则我只会使用您的原始解决方案,该解决方案的空间复杂度与其他解决方案相同。 编辑2: 正如senderle所指出的,OP根本不需要排序,而是希望应用排列。为此,您可以并且应该使用简单的索引编制方式,使其他答案显示为
[spam_list[i] for i in spam_order]
,但是仍必须进行显式或隐式复制,因为您仍然需要中间数据。 (与记录无关,为了进行记录,应用逆排列是我认为与标识并行排序的逆,虽然排序时间效率较低,但您可以使用一个获取另一个,这是.28ѭ,然后按by29ѭ排序。我离开上面有关整理记录的讨论。) 编辑3: 但是,有可能在
O(#cycles)
空间中实现就地排列,但时间效率却很差。每个置换可以分解为并行应用于子集的不相交置换。这些子集称为周期或轨道。周期等于它们的大小。因此,您迈出了信仰的飞跃,并执行以下操作:
Create a temp variable.

For index i=0...N:
    Put x_i into temp,assign NULL to x_i
    Swap temp with x_p(i)
    Swap temp with x_p(p(i))
    ...
    Swap temp with x_p(..p(i)..),which is x_i
    Put a \"do not repeat\" marker on the smallest element you visited larger than i
    Whenever you encounter a \"do not repeat\" marker,perform the loop again but
      without swapping,moving the marker to the smallest element larger than i    
    To avoid having to perform the loop again,use a bloom filter
这将在O(N ^ 2)个时间和O(#cycles)个地方运行,而不使用Bloom过滤器;如果使用它们,则在〜O(N)个时间和O(#cycle + bloomfilter_space)空间中运行     ,如果问题是特定位置的问题,而不是内存使用本身的问题(换句话说,如果您希望这样做有副作用),则可以使用切片分配。从Peter Collingridge窃取:
other_spam_list = spam_list
spam_list[:] = [spam_list[i] for i in spam_order]
assert other_spam_list == spam_list
似乎您甚至可以使用生成器表达式来执行此操作!但是我怀疑这仍然隐式地创建了某种新序列-可能是一个元组。如果没有,我认为它将表现出错误的行为。但我对其进行了测试,其行为似乎正确。
spam_list[:] = (spam_list[i] for i in spam_order)
啊哈!看到无与伦比的Sven Marnach的出色答案-生成器切片分配确实会生成一个隐式元组。这意味着它很安全,但内存效率却不如您想象的那样。不过,元组比列表更有效地利用内存,因此从该角度来看,生成器表达式是更可取的。     ,
map(lambda x:spam_list[x],spam_order)
    ,如果您实际上根本不关心效率,而只想要就地语义(这有点奇怪,因为有专门用于避免就地语义的整个编程语言),那么您可以这样做:
def modifyList(toModify,newList):
    toModify[:] = newList

def permuteAndUpdate(toPermute,permutation):
    modifyList(toPermute,[toPermute[i] for i in permutation])

permuteAndUpdate(spam_list,spam_order)

print(spam_list)
# [\'We\',\'are\',\'the\',\'Ni\',\'knights\',\'who\',\'say\']
归功于senderle,因为他们意识到这实际上是OP的追求。他应该随时将此答案复制到自己的答案中。除非您真的更喜欢他,否则不应该接受这个答案。     ,您可以使用numpy。
import numpy as np
spam_list = list(np.array(spam_list)[spam_order])
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res